I'd like to copy test.csv from folders test1 to test2, only if the file has yesterdays timestamp on. The code I'm currently working with doesn't copy my file and returns:
Not copying ...\Desktop\test1\test.csv
$DestingationFolder = "...\Desktop\test2"
$EarliestModifiedTime = (Get-date).AddDays(-1)
$Files = Get-ChildItem "...\Desktop\test1\test.csv" -File
foreach ($File in $Files)
{
if ($File.LastWriteTime -gt $EarliestModifiedTime)
{
Copy-Item $File -Destination $DestingationFolder
Write-Host "Copying $File"
}
else
{
Write-Host "Not copying $File"
}
}
Expected: Copy test.csv only if it's timestamp is from yesterday
Actual: Nothing happens and get Not copying ...\Desktop\test1\test.csv returned
Not sure if it's worth deleting the question or not but found this worked for me. Mentioned in the comments above, ... is in my paths only to make make them shorter for the question.
$DestingationFolder = "...\Desktop\test2"
$Files = Get-ChildItem "...\Desktop\test1\test.csv" -File
foreach ($File in $Files)
{
if ($File.LastWriteTime -gt (get-date).AddDays(-1).ToString("MM/dd/yyyy HH:mm:ss"))
{
Copy-Item $File -Destination $DestingationFolder
Write-Host "Copying $File"
}
else
{
Write-Host "Not copying $File"
}
}
Windows 10 64-bit. PowerShell 5
You misspelled DestinationFolder and forgot to create the folder %userprofile%\Desktop\test2
$DestinationFolder = "%userprofile%\Desktop\test2"
If(!(test-path $DestinationFolder))
{
New-Item -ItemType Directory -Force -Path $DestinationFolder
}
$EarliestModifiedTime = (Get-date).AddDays(-1)
$Files = Get-ChildItem "%userprofile%\Desktop\test1\test.csv" -File
foreach ($File in $Files)
{
if ($File.LastWriteTime -gt $EarliestModifiedTime)
{
Copy-Item $File -Destination $DestinationFolder
Write-Host "Copying $File"
}
else
{
Write-Host "Not copying $File"
}
}
Related
I wanna delete all folders from out of a list (list.txt). Before deleting them, I want to check if they are still existing.
How can I do this task? Maybe with foreach or if? I am a newbie :)
And a second task: I have this list and I want to check for the folders which are still existent and write them into a new file.
$homedirectory = get-content -Path "c:\SCO_scripts\homedirectory_delete\list.txt"
if ( Test-Path -Path $homedirectory -PathType Container ) {
Remove-item $homedirectory -Force -recurse
}
or something like that?....
$homedirectory = get-content -Path "c:\SCO_scripts\homedirectory_delete\list.txt"
foreach ($folder in $homedirectory)
{
exists -Path $folder <---??? no idea how to make it :(
Add-Content -Path C:\SCO_scripts\homedirectory_delete\newFile.txt -Value $folder
}
**would you test this please **
$folders= Get-Content -Path C:\Temp\test.txt
foreach($i in $folders){
if (Test-Path -Path $i){
Write-Host $i exist
}
else{
Write-Host $i not exist
}
}
I have found a solution.
$folders= Get-Content -Path c:\SCO_scripts\homedirectory_delete\list.txt
foreach ($folder in $folders) {
$testpath = Test-Path $folder
if ($testpath -eq $true)
{
Write-Host "$folder Folder Exists" -ForegroundColor Green
Add-Content -Path C:\SCO_scripts\homedirectory_delete\newFile.txt -Value $folder
}
else
{
Write-Host "$folder is not Online" -ForegroundColor Red
}
}
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"
I simply want to copy some files from one Directory to another. The Problem is, that the files were indeed copied, but for every file I get an error saying, that I am not authorized to Access Destination Directory.The Destination Directory shown in the error is not a Directory but a filename, actually the Name of the file actually being copied
For Example:
"C:\Users\Administrator\Desktop\temp\FileExport\Sample\archive\Arc9wa\samplesys\data\UPR00000\0000003E.bmp"
How can I Prevent this Happening? What am I doing wrong?
My Copy-File Command:
Copy-Item "$File" -Destination "$Destination" -Recurse -force
Complete Code Looks like:
[string]$samplepath = Resolve-Path /*\config\serversetup2
$first_letter= $samplepath.SubString(0,1)
$dpath=$first_letter+":"
$path = Get-Location
Copy-Item '/*\config\serversetup2' -Destination $dpath'\temp\serversetup2\' -recurse -force
$samplepath -match'(?<content>.*)config'
$respath= $matches['content']
$fileexport= "\FileExport"
[String[]]$Destination = Join-Path -Path $path -ChildPath $fileexport
[String[]]$Source = $respath
[String[]]$FilePattern = "*"
$Result = #()
Write-Host "Copying '$($Source -join ", ")' to '$($Destination -join ", ")'..." -ForegroundColor Green
$FileCount = (Get-ChildItem $Source -Recurse -File -Include $FilePattern -ErrorAction SilentlyContinue).Count
$i = 0
$NotFound = $true
$Duration = Measure-Command {
foreach ($File in (Get-ChildItem -Path $Source -Recurse -File -Include $FilePattern -ErrorAction SilentlyContinue)) {
global:$i++
Write-Progress -Activity "Copying '$($Source -join ", ")' to '$($Destination.FullName)'" -Status "Copied $i out of $FileCount..." -PercentComplete ($i/$FileCount*100)
Write-Verbose "Copying '$($Source -join ", ")' to '$($Destination.FullName)'"
foreach ($File in $Source) {
Copy-Item "$File" -Destination "$Destination" -Recurse -force
}
}
}
Write-Host "Finished Export"
Instead of using Copy-Item I am using Robocopy. There were also many Bugs in my Code. Here is my new Code working fine:
[string]$samplepath = Resolve-Path /*\temp
$samplepath -match'(?<content>.*)temp'
$respath= $matches['content']
$first_letter= $samplepath.SubString(0,1)
$dpath=$first_letter+":"
$path = Get-Location
$exppath = Join-Path -Path "$path\" -ChildPath "\FileExport"
New-Item -Path "$dpath\Sample" -ItemType Directory -force
$newpath = Join-Path -Path "$dpath" -ChildPath "Sample"
Write-Host "Starting import"
robocopy "$exppath" "$newpath" /e
Write-Host "Process finished"
I am a complete novice when it comes to powershell, but I have been given a script that I need to improve so that we can move updated or new files from one server to another. I've managed to get to grips with the current script but am struggling to find the right cmdlets and paramters to achieve the desired behaviour.
The script I have is successful at detecting changed files and moving them to a location ready for transfer to another server, but it doesn't detect any new files.
Can anyone give me some guidance as to how I would be able to achieve both behaviours?
$CurrentLocation = "C:\current"
$PreviousLocation = "C:\prev"
$DeltaLocation = "C:\delta"
$source = #{}
#
# Get the Current Location file information
#
Get-ChildItem -recurse $CurrentLocation | Foreach-Object {
if ($_.PSIsContainer) { return }
$source.Add($_.FullName.Replace($CurrentLocation, ""), $_.LastWriteTime.ToString())
}
Write-Host "Content of Source"
$source
$changesDelta = #{}
$changesPrevious = #{}
#
# Get the Previous Directory contents and compare the dates against the Current Directory contents
#
Get-ChildItem -recurse $PreviousLocation | Foreach-Object {
if ($_.PSIsContainer) { return }
$File = $_.FullName.Replace($PreviousLocation, "")
if ($source.ContainsKey($File)) {
if ($source.Get_Item($File) -ne $_.LastWriteTime.ToString()) {
$changesDelta.Add($CurrentLocation+$File, $DeltaLocation+$File)
$changesPrevious.Add($CurrentLocation+$File, $PreviousLocation+$File)
}
}
}
Write-Host "Content of changesDelta:"
$changesDelta
Write-Host "Content of changesPrevious:"
$changesPrevious
#
# Copy the files into a temporary directory
#
foreach ($key in $changesDelta.Keys) {
New-Item -ItemType File -Path $changesDelta.Get_Item($key) -Force
Copy-Item $key $changesDelta.Get_Item($key) -Force
}
Write-Host $changesDelta.Count "Files copied to" $DeltaLocation
#
# Copy the files into the Previous Location to match the Current Location
#
foreach ($key in $changesPrevious.Keys) {
Copy-Item $key $changesDelta.Get_Item($key) -Force
}
Here's a simplified approach to your needs. One thing to note is that some of the constructs I've used require PSv3+. This does not copy directory structure, just the files. Additionally, it compares the basenames (ignoring extensions) which may or may not do what you want. It can be expanded to include extensions by using .Name instead of .BaseName
#requires -Version 3
$CurrentLocation = 'C:\current'
$PreviousLocation = 'C:\prev'
$DeltaLocation = 'C:\delta'
$Current = Get-ChildItem -LiteralPath $CurrentLocation -Recurse -File
$Previous = Get-ChildItem -LiteralPath $PreviousLocation -Recurse -File
ForEach ($File in $Current)
{
If ($File.BaseName -in $Previous.BaseName)
{
If ($File.LastWriteTime -gt ($Previous | Where-Object { $_.BaseName -eq $File.BaseName }).LastWriteTime)
{
Write-Output "File has been updated: $($File.FullName)"
Copy-Item -LiteralPath $File.FullName -Destination $DeltaLocation
}
}
Else
{
Write-Output "New file detected: $($File.FullName)"
Copy-Item -LiteralPath $File.FullName -Destination $DeltaLocation
}
}
Copy-Item -Path "$DeltaLocation\*" -Destination $PreviousLocation -Force
I'm not a coder but I've still attempted tweaking PS scripts found here and still can't get the behavior I desire. The tough part for me has been the 2 digit Day requirement (dd). After several noob attempts I would like some help.
I have a folder that contains hundreds of JPG's. I manually sort these JPG's into folders based on the date taken. Folder name examples are 2015.02.04, 2016.10.31, 2016.12.01.
1) I would like a script to scan my JPG folder.
2) For each file, scan the date
3) If the file was created June 1st, 2016 then it will be moved to .\2016.06.01
Help a brother out?
$Filepath = ""
$file = ""
$date = ""
$month = ""
$year = ""
$MonthPath = ""
$FilePath = Read-Host "Place the directory which contains the files."
Write-Warning "Note: This action can take several minutes, depending on the amount of files in $FilePath."
get-childitem $FilePath | % {
$file = $_.FullName
$date = Get-Date ($_.LastWriteTime)
$month = $date.month
$year = $date.year
$day = $date.day
$MonthPath = "$FilePath\$year.$month.$day"
Write-Verbose "month = $month"
Write-Verbose "Date = $date"
Write-Verbose "year = $year"
Write-Verbose "FilePath = $FilePath"
Write-Verbose "Filename = $file"
Write-Verbose "MonthPath = $MonthPath"
if(!(Test-Path -Path "$MonthPath" )){
Write-Verbose "Creating log location $MonthPath."
#Write-Host -backgroundcolor green -ForegroundColor black "Creating log location $MonthPath."
Write-Verbose "MonthPath inside path test = $MonthPath"
New-Item -ItemType directory -Path $MonthPath | Out-null
}
ELSE {
#Write-Host -backgroundcolor green -ForegroundColor black "Log location exists already exist $MonthPath"
Write-Verbose "Log location exists already exist $MonthPath"
}
move-item "$file" "$MonthPath" | Out-null
}
Write-Warning "All files are sorted now based upon year and month."
[DateTime]$start_time="2016-6-1 00:00:00"
[DateTime]$end_time="2016-6-1 23:59:59"
$des_folder = "C:\test\2016.06.1"
Get-ChildItem c:\test\*.jpg -Recurse | foreach {if($_.lastwritetime -ge $start_time -and $_.lastwritetime -le $end_time) { move-item $_.fullname $des_folder }}
Please ensure there is no name conflict .
You may change"c:\test" in "c:\test*.jpg" to the path you want to scan .
Also the value of variable "$des_folder" to the destination folder you want to store the matched pictures .
EDIT:
Get-ChildItem c:\test\test2\*.jpg -Recurse | foreach {
$x = $_.LastWriteTime.ToShortDateString()
$new_folder_name = Get-Date $x -Format yyyy.MM.dd
$des_path = "c:\test\test2\$new_folder_name"
if (test-path $des_path){
move-item $_.fullname $des_path
} else {
new-item -ItemType directory -Path $des_path
move-item $_.fullname $des_path
}
}
I ended up creating a script that does exactly what you're asking for here. You can find it in GitHub here, which will have the latest version of the code.
Here is the current implementation, edited for conciseness, removed unnecessary features, and tailored to the question's needs:
[string] $SourceDirectoryPath = 'C:\FilesToMove'
[string] $TargetDirectoryPath = 'C:\SortedFiles'
[System.Collections.ArrayList] $filesToMove = Get-ChildItem -Path $SourceDirectoryPath -File -Force -Recurse
$filesToMove | ForEach-Object {
[System.IO.FileInfo] $file = $_
[DateTime] $fileDate = $file.LastWriteTime
[string] $dateDirectoryName = $fileDate.ToString('yyyy.MM.dd')
[string] $dateDirectoryPath = Join-Path -Path $TargetDirectoryPath -ChildPath $dateDirectoryName
if (!(Test-Path -Path $dateDirectoryPath -PathType Container))
{
Write-Verbose "Creating directory '$dateDirectoryPath'."
New-Item -Path $dateDirectoryPath-ItemType Directory -Force > $null
}
[string] $filePath = $file.FullName
Write-Information "Moving file '$filePath' into directory '$dateDirectoryPath'."
Move-Item -Path $filePath -Destination $dateDirectoryPath
}
Note that it copies the file paths into an array before iterating over them. This is important for the cases where you are copying files to subdirectories of their current directory, otherwise Get-ChildItem could scan files twice, iterating over files that it just moved.
Expanded more to cover off duplicates
$jpg_files = Get-ChildItem "F:\*.jpg" -Recurse
foreach ($jpg in $jpg_files){
$x = $jpg.LastWriteTime.ToShortDateString()
$new_folder = Get-Date $x -Format yyyy-MM-dd
$des_path = "F:\Photos\$($new_folder)"
if (Test-Path $des_path){
if (Test-Path "$($des_path)\$($jpg.Name)"){
$index = 1
do {
$new_name = $des_path + "\" + $jpg.BaseName + " ($($index))" + $jpg.Extension
$index++
} While(Test-Path $new_name)
move-item $jpg.fullname -destination $new_name
}else {
move-item $jpg.fullname $des_path
}
}
else {
new-item -ItemType directory -Path $des_path
move-item $jpg.fullname $des_path
}
I would like to propose this variant based on last response for duplicates showing that multiple files can be selected and also that removing the absolute paths works and it will move the files that are bellow of your current prompt no mathers where the file is. Also add a missing }. Thanks to all that contributes to this thread, this helps a lot to organize the pictures and video!
$files = Get-ChildItem "*.jpg","*.mp4" -Recurse
foreach ($file in $files) {
$x = $file.LastWriteTime.ToShortDateString()
$new_folder = Get-Date $x -Format yyyy-MM
$des_path = "$($new_folder)"
if (Test-Path $des_path) {
if (Test-Path "$($des_path)\$($file.Name)") {
$index = 1
do {
$new_name = $des_path + "\" + $file.BaseName + " ($($index))" + $file.Extension
$index++
} While(Test-Path $new_name)
move-item $file.fullname -destination $new_name
}else {
move-item $file.fullname $des_path
}
}
else {
new-item -ItemType directory -Path $des_path
move-item $file.fullname $des_path
}
}