SladeHD
asked on
Using Powershell, Move files while retaining folder structure
I'm trying to write a powershell script that will move any files that havn't been access in over Xdays to an archive location.
I was trying to follow along with this: http://blogs.msdn.com/b/po wershell/a rchive/200 7/04/27/fu n-with-pat hs.aspx
I can get individual parts of it to work but when i try to move the files it fails.
this is my script:
This is the error i get when i run it:
I was trying to follow along with this: http://blogs.msdn.com/b/po
I can get individual parts of it to work but when i try to move the files it fails.
this is my script:
$Source="c:\TEST\Source"
$Target="c:\TEST\Target"
$days="365"
$Now=Get-Date
$LastAccess =$Now.AddDays(-$days)
$Files=get-childitem $Source -include *.* -recurse | Where {$_.LastAccess -le “$LastAccess”}
CD $Source
foreach ($File in $Files)
{Move-Item -destination {join-path $Target $_.FullName.SubString($pwd.path.length)}}
This is the error i get when i run it:
Move-Item : Cannot evaluate parameter 'Destination' because its argument is specified as a script block and there is no inpu
t. A script block cannot be evaluated without input.
At C:\Scripts\MoveOldFiles.ps1:11 char:24
+ {Move-Item -destination <<<< {join-path $Target $_.FullName.SubString($pwd.path.length)}}
+ CategoryInfo : MetadataError: (:) [Move-Item], ParameterBindingException
+ FullyQualifiedErrorId : ScriptBlockArgumentNoInput,Microsoft.PowerShell.Commands.MoveItemCommand
Move-Item : Cannot evaluate parameter 'Destination' because its argument is specified as a script block and there is no inpu
t. A script block cannot be evaluated without input.
At C:\Scripts\MoveOldFiles.ps1:11 char:24
+ {Move-Item -destination <<<< {join-path $Target $_.FullName.SubString($pwd.path.length)}}
+ CategoryInfo : MetadataError: (:) [Move-Item], ParameterBindingException
+ FullyQualifiedErrorId : ScriptBlockArgumentNoInput,Microsoft.PowerShell.Commands.MoveItemCommand
Move-Item : Cannot evaluate parameter 'Destination' because its argument is specified as a script block and there is no inpu
t. A script block cannot be evaluated without input.
At C:\Scripts\MoveOldFiles.ps1:11 char:24
+ {Move-Item -destination <<<< {join-path $Target $_.FullName.SubString($pwd.path.length)}}
+ CategoryInfo : MetadataError: (:) [Move-Item], ParameterBindingException
+ FullyQualifiedErrorId : ScriptBlockArgumentNoInput,Microsoft.PowerShell.Commands.MoveItemCommand
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
Qlemo, Using your code (either one, with the -WhatIf removed) i get the following error:
However, when i leave the -WhatIf the output looks good:
Move-Item : Could not find a part of the path.
At C:\Scripts\MoveOldFiles.ps1:30 char:124
+ get-childitem $Source -include *.* -recurse | ? {!$_.PsIsContainer -and $_.LastAccessTime -le “$LastAccess”} | % {Move-Item <<<< $_.FullName -destination (join-path $Target $_
.FullName.SubString($Source.length))}
+ CategoryInfo : WriteError: (C:\TEST\Source\Files\TESTFILE1.txt:FileInfo) [Move-Item], DirectoryNotFoundException
+ FullyQualifiedErrorId : MoveFileInfoItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand
Move-Item : Could not find a part of the path.
At C:\Scripts\MoveOldFiles.ps1:30 char:124
+ get-childitem $Source -include *.* -recurse | ? {!$_.PsIsContainer -and $_.LastAccessTime -le “$LastAccess”} | % {Move-Item <<<< $_.FullName -destination (join-path $Target $_
.FullName.SubString($Source.length))}
+ CategoryInfo : WriteError: (C:\TEST\Source\Files\TESTFILE2.txt:FileInfo) [Move-Item], DirectoryNotFoundException
+ FullyQualifiedErrorId : MoveFileInfoItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand
Move-Item : Could not find a part of the path.
At C:\Scripts\MoveOldFiles.ps1:30 char:124
+ get-childitem $Source -include *.* -recurse | ? {!$_.PsIsContainer -and $_.LastAccessTime -le “$LastAccess”} | % {Move-Item <<<< $_.FullName -destination (join-path $Target $_
.FullName.SubString($Source.length))}
+ CategoryInfo : WriteError: (C:\TEST\Source\Files\TESTFILE3.txt:FileInfo) [Move-Item], DirectoryNotFoundException
+ FullyQualifiedErrorId : MoveFileInfoItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand
However, when i leave the -WhatIf the output looks good:
What if: Performing operation "Move File" on Target "Item: C:\TEST\Source\Files\TESTFILE1.txt Destination: C:\TEST\Target\Fil
es\TESTFILE1.txt".
What if: Performing operation "Move File" on Target "Item: C:\TEST\Source\Files\TESTFILE2.txt Destination: C:\TEST\Target\Fil
es\TESTFILE2.txt".
What if: Performing operation "Move File" on Target "Item: C:\TEST\Source\Files\TESTFILE3.txt Destination: C:\TEST\Target\Fil
es\TESTFILE3.txt".
Stupid me. Of course you need to create the folder structure first - move-item will not do that for you. So we have to use the first version:
Set-StrictMode -Version Latest
$Source="c:\TEST\Source"
$Target="c:\TEST\Target"
$days="365"
$LastAccess =(get-date).AddDays(-$days)
get-childitem $Source -include *.* -recurse `
| ? {!$_.PsIsContainer -and $_.LastAccessTime -le “$LastAccess”} `
| % {
$newpath = join-path $Target $_.FullName.SubString($Source.length)
New-Item $newpath -type directory -ErrorAction SilentlyContinue
Move-Item -WhatIf $_.FullName -destination $newpath
}
ASKER
That works but it creates a directory for every file, for example
if the Source is C:\Test\Source\ Files\File1.txt
and the Target is C:\Test\Target\
it should create C:\Test\Target\ Files\File1.txt
but instead it is doing this: C:\Test\Target\ Files\File1.txt\File1.txt
it is making a directory for every file.
any ideas on how i could get around that?
if the Source is C:\Test\Source\ Files\File1.txt
and the Target is C:\Test\Target\
it should create C:\Test\Target\ Files\File1.txt
but instead it is doing this: C:\Test\Target\ Files\File1.txt\File1.txt
it is making a directory for every file.
any ideas on how i could get around that?
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
this is what i ended up with, its working great, thanks!
Set-StrictMode -Version Latest
$Source="H:\"
$Target="E:\H Drive Archive"
$days="365"
$LastAccess =(get-date).AddDays(-$days)
get-childitem $Source -include *.* -recurse | ? {!$_.PsIsContainer -and $_.LastAccessTime -le “$LastAccess”} | % {
$newpath = join-path $Target $_.DirectoryName.SubString($Source.length)
New-Item $newpath -type directory -ErrorAction SilentlyContinue
Move-Item $_.FullName -destination $newpath
ASKER
None of the answers provided worked as they were, i had to use pieces of them and put something together.
Open in new window
Or, without using foreach-object (%), and instead having a code block in move-item:Open in new window
Remove the -whatif in both snippets to actually perform the move.