Powershell move multiple files to multiple directories - powershell

I have problems with my script. My goals is move files from multiple directories to multiple targets using LastWriteTime. When I run my script I get error code:
Move-Item : Cannot find path 'W:\files\cv\data\test.csv' because it does not exist.
At line:28 char:13
+ Move-Item -Path "$($checkThis.Source)$($file.Name)" -Dest ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (W:\files\cv\data\test.csv:String) [Move-Item], ItemNotFoundException
+ FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.MoveItemCommand
Script:
function Write-Log($str) {
Add-Content -Path $logFilePath -Value "$(Get-Date -Format "yyyy-MM-dd HH:mm:ss") $str"
}
$logpath = "C:\temp\Logs\"
$logFilePath = $logpath + "\test_files" + $(Get-Date -Format "yyyyMMdd") + ".log"
$checkThese = #(
[pscustomobject]#{Id='first'; Source='W:\files\cv\data'; Target="D:\files\archive\cv\Data\"}
[pscustomobject]#{Id='second'; Source='W:\files\tv\data'; Target="D:\files\archive\tv\Data\"}
)
#Move files from source dir to archive after this many days since last write
$archiveAfterDays = 1*1
Write-Log "[BEGIN]"
ForEach($checkThis in $checkThese) {
Write-Log "[INFO] Process $($checkThis.Id) archive"
Write-Log "[INFO] Start archive"
Write-Log "[INFO] Check folder $($checkThis.Source) for files to archive"
}
#Archive files older than $archiveAfterDays
$files = Get-ChildItem $checkThis.Source | Where-Object {$_.LastWriteTime -lt (Get-Date).AddDays(-$archiveAfterDays)}
ForEach ($file in $files)
{
Move-Item -Path "$($checkThis.Source)$($file.Name)" -Destination "$($checkThis.Target)$subfolder$($file.Name)" -Force
}
Write-Log "[END]"

Problem solved:
ForEach($checkThis in $checkThese) {
Write-Log "[INFO] Process $($checkThis.Id) Copy files to monthly DB"
Write-Log "[INFO] Start copy"
Write-Log "[INFO] Check folder $($checkThis.Source) for files to move"
$files = Get-ChildItem $checkThis.Source | Where-Object {$_.LastWriteTime -gt (Get-Date).AddDays(-1)}
ForEach ($file in $files) {
Copy-Item -Path "$($checkThis.Source)\$($file.Name)" -Destination "$($checkThis.Target)\$($file.Name)" -Force
}
}

Related

Move Item path null

I have to move files from a folder corresponding to a CSV column like that :
id
name
1a
file1
2b
file2
3c
file3
4d
file4
So if in my folder I have a file named file1 I need to create a folder named 1a and put file1 inside.
I have the following script
$CsvId = Import-Csv './test.csv'
$sourcePath= "C:\Users\olong\Desktop\object"
$dirPath = "C:\Users\olong\Desktop\dir"
$files = Get-ChildItem -Path $sourcePath | ForEach-Object -Process {[System.IO.Path]::GetFileNameWithoutExtension($_)}
$pattern = '(?<=_).*(?=_)'
ForEach ($item In $CsvId) {
$objectID = $item.'id'
$docID = $item.'name'
$location = $dirPath+ "\" + $objectID
Foreach ($file in $files) {
if($file -contains $docID) {
if (-not (Test-Path -Path $location)) {
mkdir -Path $location
}
Move-Item ($file.FullName) -Destination $location -Verbose -Force
}
}
}
But it gives me that error :
Move-Item : Cannot bind argument to parameter 'Path' because it is null.
At C:\Users\olong\Desktop\scriptMove.ps1:19 char:15
+ Move-Item ($file.FullName) -Destination $location -Verbose -Force
+ ~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidData: (:) [Move-Item], ParameterBindingValidationException
+ FullyQualifiedErrorId : ParameterArgumentValidationErrorNullNotAllowed,Microsoft.PowerShell.Commands.MoveItemCommand
With PowerShell's debugger $file is not null and with or without parenthesis on $file.FullName does nothing
I think what you want to do is to get the file(s) as mentioned in the csv under header 'name' having any extension into a subfolder as mentioned in field 'id' and create that subfolder first if it does not already exist.
If my assumtion is correct, you can try below:
$sourcePath = "C:\Users\olong\Desktop\object"
$destinationPath = "C:\Users\olong\Desktop\dir"
Import-Csv -Path './test.csv' | ForEach-Object {
$targetDirectory = Join-Path -Path $destinationPath -ChildPath $_.id
# create the output subfolder if it does not already exist
$null = New-Item -Path $targetDirectory -ItemType Directory -Force
# next use the file basename from the $_.name column as filter and move the file(s)
Get-ChildItem -Path $sourcePath -Filter "$($_.name).*" -File | Move-Item -Destination $targetDirectory
}

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

Archive files from a folder which are older than one week to a sub folder using powershell

I have tried below powershell script to move files older than 7 days from Newfolder to Archive_folder. The script is moving the entire path to the Archive_folder (means its creating folders \Users\529817\New folder in to Archive_folder and then copying files and not zipping the folder) , I need help in copying only files from NewFolder to Archive_folder and zip that folder.
$ArchiveYear = "2018"
$ArchiveMonth = "10"
$ArchiveDay = "10"
$SourcePath = "C:\Users\529817\New folder"
$TargetPath = "C:\Users\529817\New folder\Archive_folder"
$YourDirToCompress = "C:\Users\529817\New folder"
$ZipFileResult = "C:\Users\529817\New folder\Archive_folder\$ArchiveDay$ArchiveMonth.zip"
Get-ChildItem $YourDirToCompress -Directory |
#where { $_.Name -notin $DirToExclude} |
Compress-Archive -DestinationPath $ZipFileResult -Update
$Days = "7"
$LogPath = "C:Users\529817\Temp"
$Date = Get-Date -format yyyy-MM-dd_HH-mm
$TargetFolder = "$TargetPath\$Date"
$LogFile = "$LogPath\ArchiveLog-$date.txt"
$TargetZipFile = "$TargetPath\$Date.zip"
$Activity = "Move files older than $Days days from $SourcePath to $TargetFolder"
Write-Verbose $Activity
$OldFiles = Get-Childitem -Path $SourcePath -recurse | Where-Object {$_.LastWriteTime -lt (get-date).AddDays( - $days)}
$Total = $Oldfiles.Count
$Current = 0
$OldFiles | ForEach {
$Current ++
$Filename = $_.fullname
Write-Progress -Activity $Activity -Status $FileName -PercentComplete ($Current / $Total * 100)
$Split = $FileName -split '\\'
$DestFile = $split[1..($split.Length - 1)] -join '\'
$DestFile = "$TargetFolder\$DestFile"
Try {
$null = New-Item -Path $DestFile -Type File -Force
$Null = Move-Item -Path $FileName -Destination $DestFile -Force -ErrorAction:SilentlyContinue
"Successfully moved $filename to $targetfolder" | add-content $LogFile
}
Catch {
$Err = $_.Exception.Message
Write-Error $Err
"Error moving $filename`: $Err " | add-content $LogFile
}
}
You have two problems here:
Your zip file isn't going where you want it to go
Instead, all of the items which should be in the zip are going where the zip should go.
Let's figure out why this is happening so you can do what you need to get it working.
Problem 1
You have line 10 which looks like this:
Compress-Archive -DestinationPath $ZipFileResult -Update
This creates the Zip file but you don't actually do anything with this file, as in we don't see this $ZipFileResult used again in the code. This is why your zip file isn't showing up where you want it to be.
Problem 2
The end of this script has this big block where you are expressly copying the files to the directory,right where you don't want them.
Try {
$null = New-Item -Path $DestFile -Type File -Force
$Null = Move-Item -Path $FileName -Destination $DestFile -Force -ErrorAction:SilentlyContinue
"Successfully moved $filename to $targetfolder" | add-content $LogFile
}
If you only want to move the Zip file, then you can shorten this whole script. Delete everything from line 19 and on down, which begins with this line.
$OldFiles = Get-Childitem -Path $SourcePath -recurse | Where-Object {$_.LastWriteTime -lt (get-date).AddDays( - $days)}
And instead, add a Move-Item command to copy that $ZipFileResult file over to whichever directory you want it to go.
Finally, there are a number of lines which don't do anythign and can be deleted, like this line $TargetZipFile = "$TargetPath\$Date.zip"

How to zip folders using powershell

I run a program in windows powershell which lists name of files which have been modified before 30 days. I need to compress these files in a zip format. What should be the code?
#List all the folders in G:\logfiles
$folders = (Get-ChildItem -Path "G:\logfiles" | Where-Object {$_.Attributes -eq "Directory"} | Select Fullname)
#looping all folders
Foreach ($folder in $folders)
{
$files = Get-ChildItem G:\logfiles\$folder | Where{$_.LastWriteTime -lt (Get-Date).AddDays(-30)
}
Foreach ($file in $files)
{
Move-Item $file G:\logfiles\$folder\$N # *To move files to a folder name $N*
}
I will refer you to powershell 5.0 and the new Compress-Archive cmdlet
Compress-Archive -DestinationPath $folderToZip
With the down function you can compress your files.
function zipFile($Source ,$DestZip ){
$folder = Get-Item -Path $Source
$ZipFileName = $DestZip + ".zip"
set-content $ZipFileName ("PK" + [char]5 + [char]6 + ("$([char]0)" * 18))
# Wait for the zip file to be created.
while (!(Test-Path -PathType leaf -Path $ZipFileName))
{
Start-Sleep -Milliseconds 20
}
$ZipFile = (new-object -com shell.application).NameSpace($ZipFileName)
#BACKUP - COPY
$ZipFile.CopyHere($Source)
Write-Host "#Created zip file :" $DestZip
}

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
}