Move files with todays modified date to other folder then delete files older then two weeks - vba

Script needs to be run every one week (via task scheduler) and achieve the following:
When the script runs, all files on the date of script run (modified date for files) in certain folder needs to be copied to other folder, when copied, delete everything older 2 weeks from the original folder.
See screenshot for more explanation
I have something with powershell:
$path = "C:\FromFTP\*.*"
$Destination = "C:\Backup"
Foreach($file in (Get-ChildItem $path))
{
If($file.LastWriteTime -gt (Get-Date).adddays(-1).date)
{
Move-Item -Path $file.fullname -Destination $Destination
}
}
But maybe it could be also with vba..
Can someone help me with that? Thank you!

Try this:
$Path = "C:\FromFTP";
$Destination = "C:\Backup";
$Today = (Get-Date).Date;
Get-ChildItem -Path $Path |
Where-Object { ($_.LastWriteTime -ge $Today) -and ($_.LastWriteTime -lt $Today.AddDays(1)) } |
Move-Item -Destination $Destination;
Get-ChildItem -Path $Path |
Where-Object { $_.CreationTime -lt $Today.AddDays(-14) } |
Remove-Item;
The first line gets every file that was last written to (LastWriteTime) sometime between midnight today an before midnight tomorrow. Obviously it's difficult to write files tomorrow, but it makes it easy to run the script for a date in the past, too.
The second line deleted every file that was first created (CreationTime) before 14 days before today. The number of days might be off by one, depending on how you count.

Related

How to delete files based on "Last Access Time" for Powershell 5.0 and beyond?

Been pulling my hair out for a couple days trying to understand why I cannot delete (or list) files using the Last Access Time file attribute. All examples I have found on the WWW return Last Write Time... Despite passing { $_.LastAccessTime }
I think it has to do with the examples being written in PowerShell 2.0.
For example,
Get-ChildItem -Recurse -Path c:\ | Where-Object {$_.LastAccessTime -le (Get-Date).AddDays(1)}
Returns
Mode LastWriteTime Length Name
---- ------------- ------ ----
However, using
Select-Object -Property LastAccessTime, FullName
DOES Last Access Time but I don't know how to take that info and make PS delete it.
Get-ChildItem -Recurse -Path c:\ | Select-Object -Property LastAccessTime, FullName
What I want is an updated script that works in PowerShell 5.0 (or whatever Windows 2016 uses), accepts 2 parameters -- PATH and DAYS and deletes them.
Bonus to have it first move the files to a folder instead of delete, such as Archive. I will then run the same script later that can delete the files in the Archive folder.
I also have run FSUTIL (and rebooted) -
fsutil behavior set disablelastaccess 0

Passing a variable in sqlpackage containing filepath

so i am trying to exectue a ps script directly after tfs build. while the script runs post-build there is an error that says sourcefile must have a valid .dacpac extension.
Below is the code
#Powershell script to capture the latest version of the dacpac generated for the source file
$srcdir= get-childitem '\\a\b\c\d\e\f' | Where {$_.LastWriteTime} | select -last 1
$srcpathitem= Join-Path \\a\b\c\d\e\f$srcdir
$filesource= get-childitem -path $srcpathitem -filter abc.dacpac
$finalsource= Join-Path $srcpathitem $filesource
#Latest version of the target file dacpac created
$tgtdir= get-childitem '\\1\2\3\4\5\6' | Where {$_.LastWriteTime} | select -last 1
$tgtpathitem= Join-Path \\1\2\3\4\5\6 $tgtdir
$filetarget= get-childitem -path $tgtpathitem -filter EFT.dacpac
$finaltarget= Join-Path $tgtpathitem $filesource
&"\\xyz\build\xyz\xyz\Scripts\DAC\bin\SqlPackage.exe" /a:Script `
/Sourcefile:$finalsource `
/TargetFile:$finaltarget `
/op:"\\xyz\build\xyz\xyz\Scripts\123-script.sql" `
Sorry the filelocation and folder names have been given aliases due to privacy concerns.
so the third from the last is the place where the error for dacpac is coming. so pls tell how to pass the filepath so that there isn't any error. and also FYI the path cannot be hardcoded as the folder has newer versions created after some hours automatically.
Try to use
/Sourcefile:$(finalsource)`
/TargetFile:$(finaltarget)`
instead of
/Sourcefile:$finalsource `
/TargetFile:$finaltarget `
I assume your following code can get the file successfully:
$filesource= get-childitem -path $srcpathitem -filter abc.dacpac
Then if you write out "$filesource" in powershell, you can find that the value is just "abc.dacpac'. So you can try to update "/Sourcefile:$finalsource" to "/Sourcefile:$finalsource.FullName" which will return the entire file path.

Add and Remove Snapshots with PowerCLI for multiple servers

I am trying to get a snapshot from multiple servers with PowerCLI.
Connect-VIServer -server 192.168.0.1 -user acconut -password xxx
$vmlist = Get-Content C:\Users\Desktop\Test\Servers.txt
foreach($VM in $VMlist) {
New-Snapshot -VM $vm -Name Temp-SnapShot -description (get-date),'Created for patching'
}
Disconnect-VIServer -Confirm:$false
If I delete get-date, the script will work. But I need to type date in descriptions. How should I change the Script above to have Get-Date in snapshot's descriptions?
Also, I need to delete these snapshot after a couple days:
Connect-VIServer -server 192.168.0.1 -user acconut -password xxx
$vmlist = Get-Content C:\Users\Desktop\Test\Servers.txt
foreach($VM in $VMlist) {
Remove-Snapshot -VM $vm -snapshot -confirm:$false
}
Disconnect-VIServer -Confirm:$false
I could not delete snapshot with Remove-Snapshot because I get this error:
Remove-Snapshot : Missing an argument for parameter 'Snapshot'. Specify a parameter of type 'VMware.VimAutomation.ViCore.Types.V1.VM.Snapshot[]' and try again.
Thank you for your help.
On the description part you can put $date = get-date and do -description $date. That should work.
before you can remove the snapshot you need to get the snapshot. I would say edit your remove-snapshot line to include this:
Get-Snapshot -VM $vm | Remove-Snapshot -confirm:$false
you might even want to add -RemoveChildren:$true ( this will remove "All" snapshots )
This should help with what you are looking for. It finds the snaps and removes any greater than 10 days old.
$snaps = Get-VM | Get-snapshot | Select vm,name,created
if ($snaps.created -le (get-date).adddays(-10))
{
$remsnaps = $snaps | Where {$_.created -le (get-date).adddays(-10)}
$remsnaps | Out-File "C:\Scripts\RemoveSnaps\logs\remsnapsVC.txt"
$remobject = Get-Content "C:\Scripts\RemoveSnaps\logs\remsnapsVC.txt"
$rmsnap = Get-Snapshot $remsnaps.vm
Remove-Snapshot -Snapshot $rmsnap -RemoveChildren -Confirm:$false #-WhatIf
$MessageSubject = "The following snaps were removed from NTVCenter01!"
$MessageBody = $remobject | fl | out-string
SendEmail
}

Powershell - listing folders in mulitple places and changing files in those places

I'm trying to set up a script designed to change a bit over 100 placeholders in probably some 50 files. In general I got a list of possible placeholders, and their values. I got some applications that have exe.config files as well as ini files. These applications are stored in c:\programfiles(x86)\ and in d:\In general I managed to make it work with one path, but not with two. I could easily write the code to replace twice, but that leaves me with a lot of messy code and would be harder for others to read.
ls c:\programfiles(x86) -Recurse | where-object {$_.Extension -eq ".config" -or $_.Extension -eq ".ini"} | %{(gc $PSPath) | %{
$_ -replace "abc", "qwe" `
-replace "lkj", "hgs" `
-replace "hfd", "fgd"
} | sc $_PSPath; Write-Host "Processed: " + $_.Fullname}
I've tried to include 2 paths by putting $a = path1, $b = path2, c$ = $a + $b and that seems to work as far as getting the ls command to run in two different places. however, it does not seem to store the path the files are in, and so it will try to replace the filenames it has found in the folder you are currently running the script from. And thus, even if I might be in one of the places where the files is supposed to be, it's not in the other ...
So .. Any idea how I can get Powershell to list files in 2 different places and replace the same variables in both places without haveing to have the code twice ? I thought about putting the code I would have to use twice into a variable, calling it when I needed to instead of writing it again, but it seemed to resolve the code before using it, and that didn't exactly give me results since the data comes from the first part.
If you got a cool pipeline, then every problem looks like ... uhm ... fluids? objects? I have no clue. But anyway, just add another layer (and fix a few problems along the way):
$places = 'C:\Program Files (x86)', 'D:\some other location'
$places |
Get-ChildItem -Recurse -Include *.ini,*.config |
ForEach-Object {
(Get-Content $_) -replace 'abc', 'qwe' `
-replace 'lkj', 'hgs' `
-replace 'hfd', 'fgd' |
Set-Content $_
'Processed: {0}' -f $_.FullName
}
Notable changes:
Just iterate over the list of folders to crawl as the first step.
Doing the filtering directly in Get-ChildItem makes it faster and saves the Where-Object.
-replace can be applied directly to an array, no need for another ForEach-Object there.
If the number of replacements is large you may consider using a hashtable to store them so that you don't have twenty lines of -replace 'foo', 'bar'.

Renaming a list of files and creating folder in Powershell

I'm in need a script, in PowerShell or batch script, that will do the following.
Rename a file to append creation date minus 1 day to the filename.
For example:
foo.xlsx (created 7/27/2011)
foo-2011-07-26.xlsx --note, it's yesterday's date.
Date format isn't too important as long as it's there. There will be 10 files (all with the same creation date), so either I can copy and paste the same renaming line for the different files (just rename the filename) or just have the script affect all *.xlsx files in the existing folder.
Create a new folder where those files are and name it 'fooFolder-2011-07-26' (yesterday's date).
Move those renamed files to that folder.
I only have limited experience with PowerShell. It's on my todo list of languages to learn..
Here you go. It could be shortened up a lot using aliases and piping and whatnot, but since you're unfamiliar with Powershell still, I decided to write in a more procedural style for your reading:
function MoveFilesAndRenameWithDate([string]$folderPrefix, [string]$filePattern) {
$files = Get-ChildItem .\* -include $filePattern
ForEach ($file in $files) {
$yesterDate = $file.CreationTime.AddDays(-1).ToString('yyyy-MM-dd')
$newSubFolderName = '{0}-{1}' -f $folderPrefix,$yesterDate
if (!(Test-Path $newSubFolderName)) {
mkdir $newSubFolderName
}
$newFileName = '{0}-{1}{2}' -f $file.BaseName,$yesterDate,$file.Extension
Move-Item $file (Join-Path $newSubFolderName $newFileName)
}
}
You would paste the above into your Powershell session (place it in your profile). Then you call the function like this:
MoveFilesAndRenameWithDate 'fooFolder' '*.xslx'
I tend to use more aliases and piping than the above function. The first version I wrote was this, and then I separated parts of it to make it more comprehensible to a Powershell newcomer:
function MoveFilesAndRenameWithDate([string]$folderPrefix, [string]$filePattern) {
gci .\* -include $filePattern |
% { $date = $_.CreationTime.AddDays(-1).ToString('yyyy-MM-dd')
mkdir "$folderPrefix-$date" 2>$null
mv $_ (join-path $newSubFolderName ('{0}-{1}{2}' -f $_.BaseName,$date,$_.Extension))}
}
Edit: Modified both functions to create dated folder for the files that match that date. I considered making a temporary directory and grabbing a single date from the files moved to it, finally renaming the directory after the loop. However, if a day should be missed and files for 2 (or more) days get processed together, there would still be a folder for each day with these, which is more consistent.
ok i´ve made it
function NameOfFunction([string]$folderpath)
{
foreach ($filepath in [System.IO.Directory]::GetFiles($folderpath))
{
$file = New-Object System.IO.FileInfo($filepath);
$date = $file.CreationTime.AddDays(-1).ToString('yyyy-MM-dd');
if (![System.IO.Directory]::Exists("C:\\test\foo-$date"))
{
[System.IO.Directory]::CreateDirectory("$folderpath\foo-$date");
}
$filename = $file.Name.Remove($file.Name.LastIndexOf('.'));
$fileext = $file.Name.SubString($file.Name.LastIndexOf('.'));
$targetpath = "$folderpath\foo-$date" + '\' + $filename + '-' + $date + $fileext;
[System.IO.File]::Move($filepath, $targetpath);
}
}
Explanation:
First get all Files in the rootfolder.
Foreach Folder we create a FileInfo-Object and get the CreationTime -1 Day.
Then we check, if the Directory, which should be created, exists and create it if false.
Then we get the filename and the extension.
At the End we move the files to the new Directory, under the new Filename.
Hope that help you