I am writing a Powershell script to add only new files to a backup. I have a back up folder and then I add a new file after a minute and it copies all the contents where I only want the new file copied.
So as you can see I am get the files and backing them up in the $Destination folder with the timestamp. After a couple of minutes I add a new file and run the script again and it copies the new added file along with all the other files. I only want the new added file to be copied to the new backup.
What do I need to do to incorporate this??
This is my code:
function BackupArtifacts {
Param(
$FileLocation = "C:\TempCopy",
$Destination = "C:\TempCopyBackUp_" + $TimeStamp,
$StartRange = -100,
$NumberOfDays = 5
)
New-Item -ItemType Directory -Force -Path $Destination
$count = 0
foreach ($fileList in Get-ChildItem $FileLocation -recurse)
{
if ($fileList.LastWriteTime -ge ($(Get-Date)).AddDays($StartRange))
{
#Check if file already exists
try {
Copy-Item $fileList.FullName -Destination $Destination -Recurse
Write-Host $fileList.FullName
$count ++
} catch {
Write-Error $_
}
}
}
Write-Host "Backup complete, Number of files backed up:" $count
}
BackupArtifacts $FileLocation $Destination $StartRange $NumberOfDays
Related
I am trying to copy all files changed/created yesterday from a certain folder to another certain folder. It writes errors and also does not paste the files into the folder.
Here is the script:
$DestinationFolder = "D:\Dropbox\Public\Download\New folder"
If(!(test-path $DestinationFolder))
{
New-Item -ItemType Directory -Force -Path $DestinationFolder
}
$EarliestModifiedTime = (Get-date).AddDays(-1).ToString("MM/dd/yyyy")
$Files = Get-ChildItem "C:\Users\Harel Gordon\AppData\Local\Packages\Microsoft.Windows.ContentDeliveryManager_cw5n1h2txyewy\LocalState\Assets\" -File
foreach ($File in $Files)
{
if ($File.LastWriteTime.ToString("MM/dd/yyyy") -eq $EarliestModifiedTime)
{
Copy-Item $File -Destination $DestinationFolder
Write-Host "Copying $File"
}
else
{
Write-Host "Not copying $File"
}
}
Read-Host -Prompt "Press Enter to exit"
These are the errors:
enter image description here
It worked for a while then stopped. do not know why
So I have an assignment where I have to create an PowerShell script that takes three parameters, "$foldername", "$filename" and "$number".
The script checks if the folder "$foldername" exists and if not, creates it. After that it creates as many new files named "$filename" as "$number" specifies. After that it reports how many files have been created and lists them.
What I have so far.
Param (
[string]$foldername,
[string]$filename,
$number=1
)
if ((Test-Path -Path $foldername) -ne $true) {
new-item -path $foldername -ItemType directory #if the folder doesn't exist, create it.
}
$new_file= $foldername+"\$_"+$filename #save the path and name of the new file to an variable
if ((Test-Path -Path $new_file* -PathType leaf) -eq $true) {
Write-Host "$filename already exists in $foldername"
break #if a file with a name that contains $filename in it exists in $foldername, break and do not create any new files.
}
$null=1..$number | foreach { new-item -path $foldername -name $_$filename } #create new files using foreach.
write-host ("Created $number new files") #tell the user how many files were created
Get-ChildItem -path $foldername | where-object Name -like *$filename* | format-table Name #show the created files in a table format, formatted by name
There are a few problems and scuffed solutions in this script, but the main problem is the creation of the new files. Since the name of the new files come from $filename, simply running the script like so:
./script.ps1 -foldername C:\users\example\testing -filename "test.txt" -number 5
Would not work since it tries to create 5 files named "test.txt" and will just return errors.
I sort of solved it by using "foreach" and naming the files $_$filename which creates
1test.txt
2test.txt
...
5test.txt
But I found out that the correct way would be:
test1.txt
test2.txt
...
test5.txt
The number should be running in the filename somehow, but I am not sure how to do that.
Bonus points if you figure out how to check if the $filename files already exist in the target folder.
It's good to use Test-Path however I don't see a need for it here, you can use $ErrorAction = 'Stop' so that if the folder exists the script would instantly stop with a warning message. On the other hand, if the folder is a new folder there is no way the files already exist.
Param (
[parameter(Mandatory)]
[string]$FolderName,
[parameter(Mandatory)]
[string]$FileName,
[int]$Number = 1
)
$ErrorActionPreference = 'Stop'
try {
$newFolder = New-Item -Path $FolderName -ItemType Directory
}
catch {
# If the folder exists, show this exception and stop here
Write-Warning $_.Exception.Message
break
}
$files = 1..$Number | ForEach-Object {
# If this is a new Folder, there is no way the files already exist :)
$path = Join-Path $newFolder.FullName -ChildPath "$FileName $_.txt"
New-Item -Path $path -ItemType File
}
Write-Host 'Script finished successfully.'
$newFolder, $files | Format-Table -AutoSize
EDIT: I might have missed the point where you want to create the files in the folder even if the folder already exists, in that case you could use the following:
Param (
[parameter(Mandatory)]
[string]$FolderName,
[parameter(Mandatory)]
[string]$FileName,
[int]$Number = 1
)
$ErrorActionPreference = 'Stop'
$folder = try {
# If the Folder exists get it
Get-Item $FolderName
}
catch {
# If it does not, create it
New-Item -Path $FolderName -ItemType Directory
}
$files = 1..$Number | ForEach-Object {
$path = Join-Path $folder.FullName -ChildPath "$FileName $_.txt"
try {
# Try to create the new file
New-Item -Path $path -ItemType File
}
catch {
# If the file exists, display the Exception and continue
Write-Warning $_.Exception.Message
}
}
Write-Host "Script finished successfully."
Write-Host "Files created: $($files.Count) out of $Number"
$files | Format-Table -AutoSize
I want to check .jpg file in the 2nd folder. 2nd folder has some subfolder. if .jpg exist in the subfolder of 2nd folder, I will copy a file from 1st folder to subfolder of 2nd folder based on the base name. I can do this part refer to this answer
How to copy file based on matching file name using PowerShell?
But I want to do limitation while I copy a file from 1st folder. I will NOT copy the file, if I already copy the same file from 1st folder to 2nd folder 3 times.
This is the code from the reference.
$Job_Path = "D:\Initial"
$JobError = "D:\Process"
Get-ChildItem -Path "$OpJob_Path\*\*.jpg" | ForEach-Object {
$basename = $_.BaseName.Substring(15)
$job = "$Job_Path\${basename}.png"
if (Test-Path $job) {
$timestamp = Get-Date -Format 'yyyyMMddhhmmss'
$dst = Join-Path $_.DirectoryName "${timestamp}_${basename}.gif"
Copy-Item $job $dst -Force
}
Anyone can help me to solve this problem please. Thank you.
Updated
$Job_Path = "D:\Initial"
$JobError = "D:\Process"
Get-ChildItem -Path "$OpJob_Path\*\*.jpg" | ForEach-Object {
$basename = $_.BaseName.Substring(15)
$job = "$Job_Path\${basename}.png"
if (Test-Path $job) {
$timestamp = Get-Date -Format 'yyyyMMddhhmmss'
$dst = Join-Path $_.DirectoryName "${timestamp}_${basename}.gif"
$Get = (Get-ChildItem -Name "$OpJob_Path\*\*$basename.jpg*" | Measure-Object).Count
$Get
if ($Get -eq "3") {
Write-Host "Continue Other Process"
NEXT_PROCESS
} else {
Write-Host "Less than 3"
}
Copy-Item $job $dst -Force
}
$Get is not a hashtable, and it's also not keeping track of what's been copied already. You need to define the hashtable outside the loop
$copy_count = #{}
Get-ChildItem -Path "$OpJob_Path\*\*.jpg" | ForEach-Object {
...
}
and then update it whenever you copy a file
if ($copy_count[$_.Name] -le 3) {
Copy-Item ...
$copy_count[$_.Name]++
} else {
...
}
If I am using PowerShell to search for folders in a drive to move them to another folder from a CSV. I'm drawing a blank on how to leave a text file for the folder that is moved in a replacement folder.
Current PowerShell code to locate folder & move:
$File = Import-Csv C:\share\test\files.txt
foreach ($fileName in $File.FileName) {
Move-Item -Path "C:\share\test\OldLocation\$fileName" -Destination "C:\share\test\NewLocation\$fileName"
}
If I go by the title of this question and suppose you want to move files to a new location,
AND your CSV looks anything like this:
FileName
file1.docx
file2.docx
file3.docx
image1.jpg
This should do it:
$oldLocation = 'C:\share\test\OldLocation'
$newLocation = 'C:\share\test\NewLocation'
# this is the path and filename for the text to leave behind
$movedFiles = Join-Path -Path $oldLocation -ChildPath 'Files Moved.txt'
$messages = #()
$filesToMove = Import-Csv 'C:\share\test\files.txt'
foreach ($file in $filesToMove.FileName) {
$oldFile = Join-Path -Path $oldLocation -ChildPath $file
$newFile = Join-Path -Path $newLocation -ChildPath $file
if (Test-Path -Path $oldFile -PathType Leaf) {
################################################################################################
# WARNING: Using parameter '-Force' will overwrite any file in the new location with that name.
# If that is not what you want, what will be your strategy ?
################################################################################################
Move-Item -Path $oldFile -Destination $newFile # -Force
# add a new line for the text file
$messages += "File '$file' has been moved to '$newLocation'"
}
}
if ($messages.Count) {
# write the textfile with all the files that have been moved in the old location
Add-Content -Path $movedFiles -Value ($messages -join [Environment]::NewLine)
}
else {
Write-Warning "No files have been moved."
}
After the files have been moved, the old location should have a textfile containing
File 'file1.docx' has been moved to 'C:\share\test\NewLocation'
File 'file2.docx' has been moved to 'C:\share\test\NewLocation'
File 'file3.docx' has been moved to 'C:\share\test\NewLocation'
File 'image1.jpg' has been moved to 'C:\share\test\NewLocation'
I have created a script to copy the folder/sub folders/files from a specific location to a list of servers that I specified on a notepad.
It checks that if the folder has not been created, it will create it and copy over the files, but if the folder has already been created - then it stops.
However, I would like to still copy over newer files even if that folder has already been created, albeit with no subfolders or files in there.
My current code
[String] $KfxComputers = "C:\temp\Kofax Apps\servers.txt"
# This file contains the list of servers you want to copy files/folders to
$computers = get-content -Path $KfxComputers
# the folder you want to copy to the servers in the $computer variable
$sourceRoot = #("\\wdevkofx110\Kofax Software\Oracle Clients",
"\\wdevkofx110\Kofax Software\Kofax Capture 11")
# the destination location you want the file/folder(s) to be copied to
$destinationRoot = "C$\temp"
foreach ($computer in $computers) {
$testpath = Test-Path -Path \\$computer\$destinationRoot
if (!$testpath)
{
Write-Host "creating folder and copying files..." -ForegroundColor green
New-Item -ItemType Directory -Force -Path "\\$computer\$destinationRoot"
copy-item -Path $sourceRoot -Recurse -Destination
"\\$computer\$destinationRoot" -Container
} else {
Write-Host "$computer\$destinationRoot folder already exists"
}
}`
You can use Else IF
[String] $KfxComputers = "C:\temp\Kofax Apps\servers.txt"
# This file contains the list of servers you want to copy files/folders to
$computers = get-content -Path $KfxComputers
# the folder you want to copy to the servers in the $computer variable
$sourceRoot = #("\\wdevkofx110\Kofax Software\Oracle Clients",
"\\wdevkofx110\Kofax Software\Kofax Capture 11")
# the destination location you want the file/folder(s) to be copied to
$destinationRoot = "C$\temp"
foreach ($computer in $computers) {
$testpath = Test-Path -Path \\$computer\$destinationRoot
if (!$testpath)
{
Write-Host "creating folder and copying files..." -ForegroundColor green
New-Item -ItemType Directory -Force -Path "\\$computer\$destinationRoot"
copy-item -Path $sourceRoot -Destination
"\\$computer\$destinationRoot" -Container -Recurse -force
}
ElseIF ($testpath) {
Write-Host "folder already exists, copying files..." -ForegroundColor green
copy-item -Path $sourceRoot -Destination
"\\$computer\$destinationRoot" -Container -Recurse -force
}
else {
Write-Host "$computer\$destinationRoot folder already exists"
}
}`