We help IT Professionals succeed at work.

Looking for powershell help, script to copy files returns invalid cast error

General Goal

Copy files older than 1, or 2 hours to a different location, while keeping files in original place. Searching subfolders.
I settled for a script that does at least 1 day,

Script
PS D:\logs> get-childitem -path "E:\Program Files\Software\Software Name\Logs" -Recurse | where-object ($_.lastwritetime -lt (get-date).adddays(-1)) | copy-item -destination "d:\logs"

Open in new window

However i get the following back

Where-Object : Cannot bind parameter 'FilterScript'. Cannot convert value "True" to type "System.Management.Automation.
ScriptBlock". Error: "Invalid cast from 'System.Boolean' to 'System.Management.Automation.ScriptBlock'."
At line:1 char:95
+ get-childitem -path "E:\Program Files\Aspect Software\Unified IP\Logs" -Recurse | where-object <<<<  ($_.lastwritetim
e -lt (get-date).adddays(-1)) | copy-item -destination "d:\logs"
    + CategoryInfo          : InvalidArgument: (:) [Where-Object], ParameterBindingException
    + FullyQualifiedErrorId : CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.WhereObjectCommand

i don't understand enough about powershell as to why this won't work.
Comment
Watch Question

Subash SundharanIT Infrastructure Architect
CERTIFIED EXPERT
Commented:
Error is because the parameter requires Script Block to be passed, Use curly braces with where-object.

Get-childitem -path "E:\Program Files\Software\Software Name\Logs" -Recurse | where-object {$_.lastwritetime -lt (get-date).adddays(-1)} | copy-item -destination "d:\logs"

Open in new window

Top Expert 2013

Commented:
its because your "get-childitem" was returning 0 results, i think.

you need to replace your parenthesis with braces around the where clause:


get-childitem -path "E:\Program Files\Software\Software Name\Logs" -Recurse | where-object {$_.lastwritetime -lt (get-date).adddays(-1)} | copy-item -destination "d:\logs

Open in new window

Top Expert 2013
Commented:
also, if you replace 'adddays' with 'addhours', you might not have to settle for days.

Author

Commented:
@Subsun
 Excellent Thanks
@BT15
 it would be nice if that worked
 
Ok so i tried with the adddays, and the addhours, and in both cases it copied files fine, however the files modified date/time stamp were older weeks old in some cases.

sounds like the timestamp portion is not working properly
Top Expert 2013

Commented:
i tested the code on other directories of mine before reposting the code :)

try this:

instead of performing your copy statement, pipe the results to a CSV.

get-childitem -path "E:\Program Files\Software\Software Name\Logs" -Recurse | where-object ($_.lastwritetime -lt (get-date).adddays(-1)) | export-csv d:\filelist.csv -notypeinformation

Open in new window


are the files that are not being copied being included in this list? if so, then the time stamp works, its the copy that fails.

is there any more feedback from the script?
IT Infrastructure Architect
CERTIFIED EXPERT
Commented:
With condition $_.lastwritetime -lt (get-date).addhours(-1) the script will copy all files except the ones which are modified last one hour. So it's normal to see week older files..

But if you are trying to copy files modified in last one hour use
$_.lastwritetime -ge (get-date).addhours(-1)

Author

Commented:
Thanks to everyone for your help each of you provided great information that helped me fix this script and even improve upon it.

Explore More ContentExplore courses, solutions, and other research materials related to this topic.