none
Bullet Proof File Handling - Directory Iteraction RRS feed

  • Question

  • Hi

    I have a cleanup script which I got and modified from the .net. The problem was only some files were being actioned.
    I fired up powergui and tried various errorlevels, try / catch but can't beat it..
    i.e if gets an error and aborts further recursion

    What I want to happen is :

    - all directories and files (top level and sub directory) to be deleted UNLESS the files happen to end with *.msi
    - if a directory contains files AFTER deletion attempts (this will either me *.msi or files which are locked - in use) the directory is not deleted
    - locked etc, access denied should not be reported and skipped over but the recursion itself should not stop

    >> What do you recommend ?

    Thanks

    Get-ChildItem "C:\users\$env:USERNAME\AppData\Local\Temp\" -Exclude *.msi -Recurse -Force -ErrorAction Ignore | foreach { #Write-Host "File is $_

    try { remove-item -Path $_ -Exclude *.msi -Verbose -Force -recurse -ErrorAction SilentlyContinue } catch { }

    File is C:\users\me\AppData\Local\Temp\OneNoteRuntimeCache\15.0
    VERBOSE: Performing operation "Remove Directory" on Target "C:\users\me\AppData\Local\Temp\OneNoteRuntimeCache\15.0".
    VERBOSE: Performing operation "Remove file" on Target "C:\users\Sme\AppData\Local\Temp\OneNoteRuntimeCache\15.0\OneNoteRuntimeCache.onecache".
    Get-ChildItem : Access is denied
    At D:\Projects\PowerShell\test2.ps1:3 char:4
    +             Get-ChildItem "C:\users\$env:USERNAME\AppData\Local\Temp\" -Exclude *.msi -Re ...
    +    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
        + CategoryInfo          : NotSpecified: (:) [Get-ChildItem], UnauthorizedAccessException





    Monday, January 19, 2015 3:10 AM

Answers

  • Dyslexia does not cause misuse of terms. You were trying too sound cool. That is OK but it really makes your quesiton verry hard to understand.

    When you do not understand a technology it is usually best to just use plain english with no frills.  Ask any PdD and they will agree with this edict.

    -EA 0  OR -ErrorAction 0

    Sorry about the typo.  THat is why I recomend using HELP before asking.


    ¯\_(ツ)_/¯



    • Edited by jrv Monday, January 19, 2015 5:35 AM
    • Marked as answer by Greg B Roberts Monday, January 19, 2015 5:40 AM
    Monday, January 19, 2015 5:34 AM

All replies

  • You have created conflicting directives.

    What is it that you are trying to do?

    We don't support PowerGUI.

    What ia a "bullet prove file"?

    What does "being actioned" mean?

    We do not fix files copied from "the net" for end users.  THe forum is for technicians who use scripting in their professional pursuits.


    ¯\_(ツ)_/¯


    • Edited by jrv Monday, January 19, 2015 4:17 AM
    Monday, January 19, 2015 4:16 AM
  • Some answers

    - Same issue using powershell v2, i.e. it is not related to powergui (which makes looking at variables easier)

    - Not sure what happened but title should be "Bullet prove file handling" - which means that it iterates over all dirs. and files, the execption being dir or files it does not have access to,
    i.e. does not abort part way through the running.

    - this was to serve an example. I have used similar recursion before an now wondering if it may suffer the same fate.

    Thanks


    Monday, January 19, 2015 4:26 AM
  • "Bullet prove files"??

    Makes no sense in any language.

    What is it youare trying to do.  Try not to use technical language that you do not understand becise it makes it very hard to understand what you are asking.

    To remove all itme that do not have an extension of MSI you would do this.

    Get-ChildItem "C:\users\$env:USERNAME\AppData\Local\Temp\*" -Exclude *.msi -Recurse -ErrorAction 0 -File | Remove-Item


    ¯\_(ツ)_/¯

    Monday, January 19, 2015 4:43 AM
  • I thought this was clear " Not sure what happened but title should be "Bullet prove file handling" - which means that it iterates over all dirs. and files, the exception being a dir or files it does not have access to,  i.e. does not abort part way through the running."

    I will ask Microsoft Partner Support and post back the response if this resolves the issue.

     

    Get-ChildItem"C:\users\$env:USERNAME\AppData\Local\Temp\*"-Exclude*.msi -Recurse-ErrorAction0 -File| Remove-Item

    This suffers from the same  issue on certain files. 100s of files are left and only three errors (2 in use errors and one access denied which I suspect is the thing that stopped it) which suggests that is stopped the recursion.

    + ... tion 0 -File | Remove-Item
    +                    ~~~~~~~~~~~
        + CategoryInfo          : WriteError: (C:\users\xxx_error.log:FileInfo) [Remove-Item], IOException
        + FullyQualifiedErrorId : RemoveFileSystemItemIOError,Microsoft.PowerShell.Commands.RemoveItemCommand
    Get-ChildItem : Access is denied
    At line:1 char:1
    + Get-ChildItem "C:\users\$env:USERNAME\AppData\Local\Temp\*" -Exclude *.msi -Recu ...

    regards

    Monday, January 19, 2015 4:53 AM
  • You cannot remove files that are in use.

    To skip in usee file exceptions use this:

    Get-ChildItem"C:\users\$env:USERNAME\AppData\Local\Temp\*"-Exclude*.msi -Recurse-ErrorAction0 -File| Remove-Item -EA 0

    I think I know what you are trying to write. The term is "bulletproof".  This is an old term  meaning "To make immune to bullets" auchas a "bulletproof vest" or "bulletproof glass"

    For examples see: https://www.google.com/?gws_rd=ssl#newwindow=1&q=bulletproof

    Definition: http://www.merriam-webster.com/dictionary/bulletproof

    HELP is also a good way to learn how to use PowerShell commands.


    ¯\_(ツ)_/¯


    • Edited by jrv Monday, January 19, 2015 5:34 AM
    Monday, January 19, 2015 5:12 AM
  • Apologies, my dyslexia playing up.

    I assume we are trying to add a filter if the file can be accessed?

    PS C:\Users\me> Get-ChildItem "C:\users\$env:USERNAME\AppData\Local\Temp\*" -Exclude *.msi -Recurse -ErrorAction
    0 -File | Remove-Item -EQ 0
    Remove-Item : A parameter cannot be found that matches parameter name 'EQ'.
    At line:1 char:120
    + ...  | Remove-Item -EQ 0
    +                    ~~~
        + CategoryInfo          : InvalidArgument: (:) [Remove-Item], ParameterBindingException
        + FullyQualifiedErrorId : NamedParameterNotFound,Microsoft.PowerShell.Commands.RemoveItemCommand

    Monday, January 19, 2015 5:27 AM
  • Dyslexia does not cause misuse of terms. You were trying too sound cool. That is OK but it really makes your quesiton verry hard to understand.

    When you do not understand a technology it is usually best to just use plain english with no frills.  Ask any PdD and they will agree with this edict.

    -EA 0  OR -ErrorAction 0

    Sorry about the typo.  THat is why I recomend using HELP before asking.


    ¯\_(ツ)_/¯



    • Edited by jrv Monday, January 19, 2015 5:35 AM
    • Marked as answer by Greg B Roberts Monday, January 19, 2015 5:40 AM
    Monday, January 19, 2015 5:34 AM
  • PS - "bulletproof' is one word.


    ¯\_(ツ)_/¯

    Monday, January 19, 2015 5:36 AM
  • Thank you (and chastened)

    Monday, January 19, 2015 5:42 AM
  • Thank you (and chastened)

    Don't get me wrong.  I am not picking on you but I am posting this for others who may see this.

    Just ask simple questions. 

    When I have issues and need help I always try to ask the simplest, dumbest question. THis makes it easier to understand.

    When I wanted to understand how to use a very technical method with an Oracle database years ago I had to dummbdownthe question.

    How?   I searched for my initial question. "How to use slowly changing dimensions in Oracle".  I got nothing but gibberrish back.  After a few more tries I went to an Oracle forum and asked "How do I implement DW dimensions that accommodate change over time?"

    I got an answer almost immediately.  I just types "oracle slowly changing dimensions" into google and now I get an answer. 10 years ago that answer was not searchable.

    Simplicity rules in science, engineering and technology.  If you are trying to be cute be sure you fully understand the technology first.

    These are all my opinions and have nothing to do with this forum or the larger universe.

    As George Carlin once said:

    "And...and some of this stuff is just silly, we all know that, like on the airlines, they say want to pre- board.  Well, what the hell is pre-board, what does that mean?  To get on before you get on?  They say  they're going to pre-board those passengers in need of special assistance.  Cripples!  Simple honest direct  language."


    ¯\_(ツ)_/¯


    • Edited by jrv Monday, January 19, 2015 6:07 AM
    Monday, January 19, 2015 6:06 AM
  • The following works and gives finer control but requires more code.
    The previous approach still caused the script to stop.

    I have written in a general sense with comments so others can modify.

    $ErrorActionPreference = "SilentlyContinue"

    $global:LevelCount = 0

    $global:MaxLevelCount = 0

    $global:TotalFileCount = 0

    $global:TotalDirCount = 0

    $global:TotalFileSize = 0

    $DirFlag = [int]([System.Io.FileAttributes]::Directory)

    $JunctionFlag = [int]([System.Io.FileAttributes]::ReparsePoint)

    <#

    .SYNOPSIS

    Recurse direcory, first go through all the files then each directory

    .DESCRIPTION

    Recurse direcory, first go through all the files then each directory

    then repeat this patterm in subdirectories, the code has a section for file and dir handling

    .NOTES

     Authors:  Greg Roberts

    .PARAMETER String Path

     Path to top level directory

    .PARAMETER Int Recurse_Flag

     Used internally, do not add

     #>

    Function Recurse_Files{

        Param(

            [Parameter(Mandatory=$True)]

            [string]$Path,

                [Parameter(Mandatory=$False)]

            [int]$Recurse_Flag = 0

                )

       

          if ($Recurse_Flag -eq 0)

          {

                # first time...

                $global:TotalFileCount = 0

                $global:TotalDirCount = 0

                $global:TotalFileSize = 0

                $global:MaxLevelCount = 0

          }

          $global:LevelCount++

          if ($global:LevelCount -gt $global:MaxLevelCount)

          {

                $global:MaxLevelCount = $global:LevelCount

          }

          $Files = 0

          $Dirs = 0

          $FileSize = 0

          [int[]] $theStats = 0,0,0

         

          Write-Host "Inside " $Path

         

          #

          # Exclusions can be added here (-Exclude *.msi) or in the logic below

          #

         

        ForEach($file in (Get-ChildItem $Path -force -ErrorAction silentlycontinue))

          {

                try

                {

                      # Do not follow reparse points, i.e. junctions

                      if (([int]$file.Attributes -band $JunctionFlag) -eq 1)

                      {

                            Continue

                      }

                     

                      if (([int]$file.Attributes -band $DirFlag) -eq $DirFlag)

                      {

                            # Directory section

                           

                            # Continue down to bottom so that we do things bottom up

                            # By placing this Recusion call on the other side of the "work" you can drill top down

                            Recurse_Files $file.FullName 1

                            $Dirs++

                            $global:TotalDirCount++

                           

                            #

                            # Do File work here, NB: this will not include the original parent directory called

                            #

                            if ((Get-ChildItem $file.FullName).Count -eq 0)

                            {

                                  Write-Host "Deleting " $file.FullName

                                  remove-item -Path $file.FullName -Exclude *.msi -Verbose -Force -Recurse -ErrorAction SilentlyContinue

                            }

                            else

                            {

                                  Write-Host "NOT Deleting " $file.FullName

                            }

                    }

                      else

                      {

                            #

                            # File section

                            #

                            $Files++

                            $global:TotalFileCount++

                            $global:TotalFileSize += $file.Length

                            $FileSize += $file.Length

                            #

                            # Do file work here

                            #

                            if ($file.ModifyTime -gt $(Get-Date).AddDays(-7))

                            {

                                  Write-Host "Deleting " $file.FullName

                                  remove-item -Path $file.FullName -Exclude *.msi -Verbose -Force -ErrorAction SilentlyContinue

                            }

                            else

                            {

                                  Write-Host "Not deleting because modified recently " $file.FullName

                            }

                      }

                }

                catch

                {

                }

          }

          $global:LevelCount--

          #

          # When this is zero we are back to the top level if something needs to be done

          #

    }

    Recurse_Files "C:\users\$env:USERNAME\AppData\Local\Temp\" 

    Write-Host

    Write-Host "Stats Dirs " $global:TotalDirCount ", files " $global:TotalFileCount

    Tuesday, January 20, 2015 5:42 AM
  • "bulletproof' does not mean you need to post 1000+ lines of code.


    ¯\_(ツ)_/¯

    Tuesday, January 20, 2015 8:58 AM