need a sample powershell script which will delete the file older than 3 days

I have file server which keep log data of many applications.
log data will created for many applications.
log data will be created for an application,only if there is any errors get generated.
for each application logs will be generated under specific folders.i.e. each application logs are maintained under separate folder.
so i am looking for a script which will dynamically calculates the date of files under each folder in e: drive and delete log files which are older than 3 days.

I don't to dependent upon schedule task, whenever new files is created and if it finds a files which are older than 3 days in that path, it should delete it immediately.
LVL 5
VIVEKANANDHAN_PERIASAMYAsked:
Who is Participating?
 
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
Please review http:#a37053069, which shows the correct commands.
In the last code, using     | % { $_.FullName } | % {remove-item $_.FullName }    is wrong. The first part will put the string stored in $_.FullName into the pipe, and hence the follow-up commands just would need to use that string as $_, not $_.FullName. Tout la phrase:
gci "E:\" -include *.log -recurse | ? { ((get-date) - $_.LastWriteTime).Days -gt 3 } | % { $_.FullName } | % {remove-item $_ -whatIf}

Open in new window

To answer to developedtester's question: As you can see the command will not work that way. And it does not print anything. But the buffering and intermixing of command output and errors is an issue if you process the output further, which is not the case here. Errors will be sent out immediately, while the command output might get processed, collected, delayed, reduced, whatever, and then displayed. There might be no connection between an error message and the command output. However, if we force output to be sent to the console with write-host, it is more "synchronous" with error messages. So I guess what you wanted to achieve is:
gci "E:\" -include *.log -recurse | ? { ((get-date) - $_.LastWriteTime).Days -gt 3 } | % { write-host "Processing: " $_.FullName; remove-item $_ -whatIf}

Open in new window

0
 
Bryan ButlerCommented:
You will need to either have a script which is running all the time (endless loop), or you will ned to create a service (that's running all the time).  Here's a simple script that deletes file in the e:\ drive that are greater than (-gt) 3 days old.

$Files = get-childitem "e:\" -include *.log -recurse | Where {$_.LastWriteTime -gt "3"}
  foreach ($File in $Files) {
    remove-item $File
    write-host "File deleted: $File"
}

Let us know if you want a service or just a loop.
0
 
VIVEKANANDHAN_PERIASAMYAuthor Commented:
i like to ave a service
0
How do you know if your security is working?

Protecting your business doesn’t have to mean sifting through endless alerts and notifications. With WatchGuard Total Security Suite, you can feel confident that your business is secure, meaning you can get back to the things that have been sitting on your to-do list.

 
Bryan ButlerCommented:
To create a service follow these steps here: http://support.microsoft.com/kb/137890

Then just create the script and put the command in the registry:

"powershell c:\<path to your script>\<script_name>.ps1"
0
 
VIVEKANANDHAN_PERIASAMYAuthor Commented:
there is sometime missing in the script.

Where {$_.LastWriteTime -gt "3"}
it gives a error system.datetime cannot covert the value 3

i trying debug it
0
 
VIVEKANANDHAN_PERIASAMYAuthor Commented:
I am getting below error,
Bad argument to operator '-gt': Could not compare "29-08-2011 22:10:29" to "3". Error: "Cannot convert value "3" to
type "System.DateTime". Error: "String was not recognized as a valid DateTime."".
At line:1 char:83
+ $Files = get-childitem "e:\" -include *.log -recurse | Where {$_.LastWriteTime -gt <<<<  "3"}
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : BadOperatorArgument
 
Bad argument to operator '-gt': Could not compare "29-08-2011 19:53:05" to "3". Error: "Cannot convert value "3" to
type "System.DateTime". Error: "String was not recognized as a valid DateTime."".
At line:1 char:83
+ $Files = get-childitem "e:\" -include *.log -recurse | Where {$_.LastWriteTime -gt <<<<  "3"}
    + CategoryInfo          : InvalidOperation: (:) [], RuntimeException
    + FullyQualifiedErrorId : BadOperatorArgument
 
Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
At line:3 char:16
+     remove-item <<<<  $File
    + CategoryInfo          : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveIt
   emCommand
0
 
Bryan ButlerCommented:
Oops, date math...try this:

$Files = get-childitem "e:\" -include *.log -recurse | Where {(get_date.Date - $_.LastWriteTime).Days -gt "3"}
  foreach ($File in $Files) {
    remove-item $File
    write-host "File deleted: $File"
}
0
 
VIVEKANANDHAN_PERIASAMYAuthor Commented:
Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
At line:4 char:16
+     remove-item <<<<  $File
    + CategoryInfo          : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveIt
   emCommand

this is error i am getting
0
 
Bryan ButlerCommented:
Then there is no "e:\" drive/path accessible.  Can you change that value or map the drive?
0
 
Bryan ButlerCommented:
Or actually, change the permissions.  Is it deleting any files?  Change the code to this to see what file is failing:

$Files = get-childitem "e:\" -include *.log -recurse | Where {(get_date.Date - $_.LastWriteTime).Days -gt "3"}
  foreach ($File in $Files) {
    write-host "File to be deleted: $File"
    remove-item $File
    }
 
0
 
VIVEKANANDHAN_PERIASAMYAuthor Commented:
no luck!

File deleted:
Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
At line:5 char:16
+     remove-item <<<<  $File
    + CategoryInfo          : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveIt
   emCommand
 
File to be deleted:
Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
At line:10 char:16
+     remove-item <<<<  $File
    + CategoryInfo          : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveIt
   emCommand
0
 
VIVEKANANDHAN_PERIASAMYAuthor Commented:
I also changed to c:\ drive but no luck!
0
 
Bryan ButlerCommented:
It only get the filename and it needs the fullname with the path.  Try:

$Files = get-childitem "e:\" -include *.log -recurse | Where {(get_date.Date - $_.LastWriteTime).Days -gt "3"}
  foreach ($File in $Files) {
    write-host "File to be deleted: $File"
    remove-item $File.fullname
    }
0
 
VIVEKANANDHAN_PERIASAMYAuthor Commented:
Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
At line:4 char:16
+     remove-item <<<<  $File.fullname
    + CategoryInfo          : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
    + FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveIt
   emCommand

issue still persisting
0
 
Bryan ButlerCommented:
What did it print for the "file to be deleted"?  Try deleting the file from the command line with the remove-item command and see if you get the same error.  If so, then it's a permissions thing.
0
 
VIVEKANANDHAN_PERIASAMYAuthor Commented:
i am able to delete the file by remove-item command but not able to delete by script.
this the output i got:

File to be deleted:
Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
At D:\Documents and Settings\vinod\Desktop\del.ps1:4 char:16
+     remove-item <<<<  $File.fullname

I tried on my local pc, but it gave me the same result.
0
 
VIVEKANANDHAN_PERIASAMYAuthor Commented:
I tried executing $Files = get-childitem "e:\" -include *.txt -recurse | Where {$_.LastWriteTime -gt "3"}
command alone.
and found
The term 'get_date.Date' is not recognized as the name of a cmdlet, function, script file, or operable program. Chec
k the spelling of the name, or if a path was included, verify that the path is correct and try again.
At line:1 char:81
+ $Files = get-childitem "c:\sccm" -include *.txt -recurse | Where {(get_date.Date <<<<  - $_.LastWriteTime).Days -g
t "3"}
    + CategoryInfo          : ObjectNotFound: (get_date.Date:String) [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException
error.

I feel there is some issue with the first staement itself
0
 
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
1. The line you "executed" isn't the line you executed, that is the line doesn't fit to the error message.

2. There are several errors in the line provided by developedtester. It needs to be
$Files = get-childitem "e:\" -include *.log -recurse | Where { ((get-date) - $_.LastWriteTime).Days -gt 3} 

Open in new window

get-date is a commandlet, so it needs to be enclosed in parens if used in an expression. Further, .Days returns an integer, not a string, so comparing it against "3" can result in misbehaviour (ok, not with "3", but imagine you want to use "30" - "4" is greater than that ...).

For many reasons it is usually not a good idea for commands running significantly and/or producing a bigger result set to store them in a var, just to stuff them into foreach. This eats up both time and memory unnecessarily. So I advice to use something like this:
gci "E:\" -include *.log -recurse | ? { ((get-date) - $_.LastWriteTime).Days -gt 3 } | % {remove-item $_.FullName -whatIf}

Open in new window

Remove the -whatIf if you want to execute the deletion of files.
0
 
Bryan ButlerCommented:
Thanks for catching those Qlemo.  I agree about stuffing them in a var, but it does make debugging easier, also easier to read, and wouldn't the results of the one pipe get stored temp var in memory till it's all pumped into the next part?  And taking that and putting it in a variable wouldn't really take more memory, eh?  Time yes, but memory?  Anyway, this would should work:

$Files = get-childitem "e:\" -include *.log -recurse | Where {((get-date).Date - $_.LastWriteTime).Days -gt 3}
  foreach ($File in $Files) {
    write-host "File to be deleted: $File"
    remove-item $File.fullname
    }
 
0
 
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
>> wouldn't the results of the one pipe get stored temp var in memory till it's all pumped into the next part
No. There are many cmdlets which can work asynchronously. ForEach-Object is one of them. The piped object stream is processed while it is generated, as we are used by UNIX tools. As soon as a pipe object is processed, it can be dismissed, and memory reused.
Another advantage is that you often can just apply cmdlets on the pipe, and they select what they need from the object by themselves. Remove-Item however needs the file name (or object path) .
0
 
Bryan ButlerCommented:
Excellent.  Thanks!  So adding printing would be:

gci "E:\" -include *.log -recurse | ? { ((get-date) - $_.LastWriteTime).Days -gt 3 } | % { $_.FullName } | % {remove-item $_.FullName -whatIf}

Do you know if it prints the filename and immediately any error message for the "remove" command for that file?  Or does is batch the output/processing so you aren't sure what error the file is for unless it's in the error message because it's not guarenteed to be in order.
0
 
VIVEKANANDHAN_PERIASAMYAuthor Commented:
It didn't delete any file and didn't give any output.

So I changed script as
gci "D:\Documents and Settings\vinod\Desktop\hindi"  -recurse | ? { ((get-date) - $_.LastWriteTime).Days -gt 3 } | % { $_.FullName } | % {remove-item $_.FullName }

but found below error:
Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
At D:\Documents and Settings\vinod\Desktop\del.ps1:1 char:149
+ gci "D:\Documents and Settings\vinod\Desktop\hindi" -recurse | ? { ((get-date) - $_.LastWriteTime).Days -gt 3 } | % {
 $_.FullName } | % {remove-item <<<<  $_.FullName}
0
 
Bryan ButlerCommented:
Thanks for the explination.  Typically this would be logged.  Is there a "verbose" or another way to do it?  Otherwise for/next would be needed.  Could you at least put a try/catch in for errors?
0
 
QlemoBatchelor, Developer and EE Topic AdvisorCommented:
try/catch is useful if you need to perform special action on error. In this particular case I would refrain from using it - not deleting the files 3 days old now will not harm, next round they might get deleted anyway. Capturing errors here would make the script too complicated, IMHO. I would just log the error messages, nothing more.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.