PowerShell copying folders from a backup Folder with date to destination folder - powershell

I have a folder on a net share - call it \Server\Backup\November.25.2013.backup.
This folder has the sub folders \test1, \test2, \test3.
Example:
\\Server\Backup\November.25.2013.backup\
.\Test1
.\Test2
.\Test3
I need to copy the sub folders of November.25.2013.backup to c:\Test.
This function is only to copy the backup folder contents of a specified day (in this case yesterday's backup). I am using this script to restore the last day's backup minus the name (November.25.2013.backup). Here is what I have been trying to utilize:
Get-ChildItem -Path \\Server\Backup -r | Where-Object {$_.LastWriteTime -gt (Get-Date).Date}
% { Copy-Item -Path $_.FullName -Destination C:\Test -WhatIf }
However I get the error
Copy-Item : Cannot bind argument to parameter 'Path' because it is null.
At line:3 char:20
+ % { Copy-Item -Path <<<< $_.fullname -destination C:\Test -whatif }
+ CategoryInfo : InvalidData: (:) [Copy-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand
Please understand that I am still a greenhorn with Powershell scripting and I am not sure how to troubleshoot this. I appreciate any advice.
My goal is to restore folders from a backup folder. Thanks.

You are missing a pipe at the end of the first line.
Also, If you are trying to get a folder with a last write time of yesterday, it would be less than -lt the current date
Get-ChildItem -Path \\Server\Backup -r | Where-object {$_.lastwritetime -lt (get-date).date} |
% { Copy-Item -Path $_.fullname -destination C:\Test -whatif }
But that might grab more history than you want if there is a folder for every day. If you only wanted what was written yesterday use this:
Get-ChildItem -Path \\Server\Backup -r | Where-object {($_.lastwritetime.date -eq ((get-date).adddays(-1)).date)} |
% { Copy-Item -Path $_.fullname -destination C:\Test -whatif }
Example from comment:
Get-ChildItem -Path c:\test -r | Where-object {$_.PSIscontainer -and (($_.lastwritetime.date -eq ((get-date).adddays(-1)).date))} |
% { Copy-Item $_.fullName -destination C:\Testoutput\ -recurse}

(Adding as an answer as well.)
In your pasted code, there is no pipe between the Where-Object and %.
Simple solution: add a | to the end of the first line:
Get-ChildItem -Path \\Server\Backup -r | ? {$_.lastwritetime -gt (get-date).date} |
% { Copy-Item -Path $_.fullname -destination C:\Test -whatif }

Related

PowerShell copy-item

I am trying to copy latest 30days files to the folder by this code:
$month = (get-date).AddDays(-30).ToString("yyyMM")
$lastmonthfiles = Write-Host (-join('DCP_', $month,"*.csv"))
Copy-Item -Path Write-Host (-join ("C:\DC+\History\", $lastmonthfiles)) -Destination C:\DC+\History\Backup
but I am having a problem in path in copy-item instruction, which is
Copy-Item : A positional parameter cannot be found that accepts argument 'C:\DC+\History\'.
At line:5 char:1
+ Copy-Item -Path Write-Host (-join ("C:\DC+\History\", $lastmonthfiles ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Copy-Item], ParameterBindingException
+ FullyQualifiedErrorId : PositionalParameterNotFound,Microsoft.PowerShell.Commands.CopyItemCommand
I am new in PowerShell, and programming so, I could not understand, how can I update and achieve a goal.
Try this:
$Source = Get-Item "C:\Games"
$Destination = "E:\Backup"
$LogFile = "C:\Copy-LogFile.txt"
Copy-Item -Path $( $Source | Where LastWriteTime -LE (Get-Date).AddDays(-30) ) -Destination $Destination -Recurse -PassThru |
Out-File $LogFile -Force
This takes care of your copy function and generates an output log.
Sorry, but your code makes no sense to me...
If it is your aim to copy files to a subfolder in a backup path, try this:
# get the date to use as subfolder to copy to and also to filter the last 30 days files
$refDate = (Get-Date).AddDays(-30).Date # .Date sets it to midnight
# set this variable to the folder where the csv are to be found
$sourceFolder = 'X:\Path\To\Where\The\Files\Are'
# create a destination path to copy to (just a string)
$destination = Join-Path -Path 'C:\DC+\History\Backup' -ChildPath ($refDate.ToString("yyyMM"))
# create this destination folder
$null = New-Item -Path $destination -ItemType Directory -Force
# get the files and copy them to the destination folder
Get-ChildItem -Path $sourceFolder -Filter '*.csv' -File | # filter on CSV fies only
Where-Object { $_.LastWriteTime -ge $refDate } | # filter on date 'last 30 days'
Copy-Item -Destination $destination -Force

Powershell error when deleting old files and folders

I'm trying to delete some old files in an archive folder and my script works fine until it gets to the last section where it removes the empty folders (testing using -whatif initially). I get the following error:
Remove-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\ArchiveDelete.ps1:13 char:39
+ $dirs | Foreach-Object { Remove-Item <<<< $_.fullname -whatif }
+ CategoryInfo : InvalidData: (:) [Remove-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.RemoveItemCommand
Tried to find a suitable answer on here but can't find a solution (I know I may be using an older version of Powershell)
#Days older than
$HowOld = -900
#Path to the root folder
$Path = "C:\SharedWorkspace\ArchiveDSAgile"
#Deletion files task
get-childitem $Path -recurse | where {$_.lastwritetime -lt (get-date).adddays($HowOld) -and -not $_.psiscontainer} |% {remove-item $_.fullname -force -whatif}
#Deletion empty folders task
do {
$dirs = gci $Path -recurse | Where { (gci $_.fullName -Force).count -eq 0 -and $_.PSIsContainer } | select -expandproperty FullName
$dirs | Foreach-Object { Remove-Item $_ -whatif }
} while ($dirs.count -gt 0)
None of your loops are necessary.
You can feed the output of Where-Object right into Remove-Item
$AgeCap = (Get-Date).AddDays(-900)
$Path = "C:\SharedWorkspace\ArchiveDSAgile"
Get-ChildItem $Path -Recurse -File | Where-Object LastWriteTime -lt $AgeCap | Remove-Item -WhatIf
The -File parameter for Get-ChildItem available in PowerShell 3.0 (I believe) and higher. The Workaround for PowerShell 2.0 would be checking against $_.PSIsContainer in Where-Object, as you did in your sample code.
Finally got it working:
#Days older than
$HowOld = -900
#Path to the root folder
$Path = "C:\SharedWorkspace\ArchiveDSAgile"
#Deletion files task
get-childitem $Path -recurse | where {$_.lastwritetime -lt (get-date).adddays($HowOld) -and -not $_.psiscontainer} |% {remove-item $_.fullname -force -whatif}
#Deletion empty folders task
Get-ChildItem $Path -Recurse | Where-Object {$_.lastwritetime -lt (get-date).adddays($HowOld) -and -not !$_.psiscontainer} | Remove-Item -recurse -WhatIf
Thanks for your help

Deleting Files Older than 30 Days with Powershell

I am trying to delete all files in a directory and all files in its sub-directories older than 30 days, leaving all folders intact. This question seems to have been asked to death online and I have this solution which i got from Stackoverflow:
$limit = (Get-Date).AddDays(-30)
$path = "path-to"
# Delete files older than the $limit.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsContainer -and $_.CreationTime -lt $limit } | Remove-Item -Force
Now this works and it doesn't.
When I try this on certain directories it works fine and exits normally. But when I try it on others I get this error:
Get-ChildItem : The given path's format is not supported.
At C:path-to-whatever\ClearFiles.ps1:5 char:1
+ Get-ChildItem -Path $path -Recurse -Force | Where-Object { !$_.PSIsCo ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [Get-ChildItem], NotSupportedException
+ FullyQualifiedErrorId : System.NotSupportedException,Microsoft.PowerShell.Commands.GetChildItemCommand
I assume this is because of the time format in $._CreationTime, I have tried to remove this but when I do it continually asks me if i really want to delete the following files because I have not specified the recursive parameter, which I have at the beginning.
Could anyone clear this up? And perhaps explain why it works on some directories and not others.
Cheers
I couldn't reproduce your issue with the following code, but I will explain how I did it with some error handling ideas.
Lets first compare the two variables.
$_.LastWriteTime = Last time the file was written to.
$_.CreationTime = Time the file was created or Copy and pasted.
Adding the Out-GridView with the Select statement will provide us with a list of files on that path. I have added the Name, Attributes, CreationTime, LastWriteTime, and Fullname.
Get-ChildItem -Path $path -Recurse -Force | Where-Object { $_.CreationTime -lt $Date } | Select Name, Attributes, CreationTime, LastWriteTime, Fullname | Out-GridView
If you Run As Administrator you could see more files. Certain hidden directories requires Run As Administrator.
Remove-Item has a really nice option of -WhatIf. What if we decide to delete the folders and files. WhatIf option doesn't delete, but it will show you what would have been deleted. Great for testing.
Get-ChildItem -Path $path -Recurse | Where-Object { $_.CreationTime -lt $Date } | Remove-Item -Recurse -whatif
Lets put this into a working Function with some error handling:
Function Remove_FilesCreatedBeforeDate{
$Path="F:\ISO\"
$Date=(Get-Date).AddDays(-30)
$ValidPath = Test-Path $Path -IsValid
If ($ValidPath -eq $True) {
Write-Host "Path is OK and Cleanup is now running"
#Get-ChildItem -Path $path -Recurse | Where-Object { $_.CreationTime -lt $Date } | Select Name, Attributes, CreationTime, LastWriteTime, Fullname | Out-GridView
#Get-ChildItem -Path $path -Recurse | Where-Object { $_.CreationTime -lt $Date } | Remove-Item -Recurse -whatif
Get-ChildItem -Path $path -Recurse | Where-Object { $_.CreationTime -lt $Date } #| Remove-Item -Recurse -Verbose
}
Else {Write-Host "Path is not a ValidPath"}
}
Remove_FilesCreatedBeforeDate
You only see the Warning\Confirm menu when you are about to delete a folder structure. What a lot of people fail to understand is the -Force option only removes hidden files and read-only files. We will want to use the -Recurse option to avoid this prompt, but note that it will delete everything.
I have commented out the Remove-Item for safety reasons.
#| Remove-Item -Recurse -Verbose
This works with $Path options like \\SERVER\$C\Directory\ or C:\Directory\. Let me know if you have any issues with this function.

Parameter Binding

I'm trying to create a PowerShell script that will move XML files of a certain age to a network drive to be archived. The script thus far:
$qaprocessedpath = "Y:\SFTPSHARE\SFTPYMSQ\YS42C1Processed"
$qabackup = “\\servername\S$\xmlbackup\qa"
$max_age_qa = "-1"
$curr_date = Get-Date
$del_date_q = $curr_date.AddDays($max_age_qa)
Get-ChildItem -include *.xml $qaprocessedpath | Where-Object {$_.LastWriteTime -lt $del_date_q } | Foreach-Object {Copy-Item -Path $_.FullName -Destination $qabackup} {Remove-Item $_.FullName}
This code leads to the following error:
Copy-Item : Cannot bind argument to parameter 'Path' because it is null.
At Y:\SFTPSHARE\SFTPYMSP\XMLBackup.ps1:52 char:132
+ Get-ChildItem -include *.xml $qaprocessedpath | Where-Object { $_.LastWriteTime -lt $del_date_q } | Foreach-Object {Copy-Item -Path <<<< $_.FullName -Destination $qabackup} {Remove-Item $_.FullName}
+ CategoryInfo : InvalidData: (:) [Copy-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.CopyItemCommand
Not sure where the issue is. I'm a novice scripter, so I'm sure it's something obvious...
In this line
Get-ChildItem -include *.xml $qaprocessedpath | Where-Object {$_.LastWriteTime -lt $del_date_q } | Foreach-Object {Copy-Item -Path $_.FullName -Destination $qabackup} {Remove-Item $_.FullName}
Why do you have two scriptblocks following the Foreach-Object?
Try separating the copy-item and remove-item with semicolons (in the same scriptblock) if you want them both to run. As you wrote it, the two scriptblocks are getting bound to the -Process parameter (as usual) and the -Begin parameter.

Move-Item not reading the path correctly

I have this script where i want to move files from one path to another:
$logArchieveDirectory='C:\LogArchieve\'+$archiveTillDate.Day+$archiveTillDate.Month+$archiveTillDate.Year;
$sourcePathServer = 'C:\DDS\Server\LOGS';
$destPathServer=$logArchieveDirectory+'\Server';
#Create Directories
New-Item -ItemType directory -Path $logArchieveDirectory;
New-Item -ItemType directory -Path $destPathServer;
#Moving Logs to new temporary log archieve directories
foreach( $item in (Get-ChildItem $sourcePathServer | Where-Object { $_.CreationTime -le $archiveTillDate }) )
{
Move-Item $item $destPathServer -force;
}
However, i have specified both paths fine But i keep getting this error when i run this script.
Move-Item : Cannot find path 'C:\DDS\WorkFolder\WebAdapter' because it does not exist.
At C:\DDS\WorkFolder\powerShellScript08062014.ps1:38 char:11
+ Move-Item <<<< $item $destPathController;
+ CategoryInfo : ObjectNotFound: (C:\DDS\WorkFolder\WebAdapter:String) [Move-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveItemCommand
The C:\DDS\WorkFolder\ is actually the folder where my script file is located. But what i am not understanding is why it is looking for the folder here and not where the path is given i.e. $sourcePathServer?
Your script passes relative paths to Move-Item and it defaults to the working directory. An easy solution is to pass absolute paths using .FullName property:
foreach ($item in (Get-ChildItem $sourcePathServer `
| Where-Object { $_.CreationTime -le $archiveTillDate })) {
Move-Item $item.FullName $destPathServer -force
}
Also using foreach in conjunction with pipelines doesn't look very elegant because of all the parentheses. You can get rid of it:
Get-ChildItem $sourcePathServer `
| Where-Object { $_.CreationTime -le $archiveTillDate } | Foreach-Object {
Move-Item $_.FullName $destPathServer -Force
}