Question

Current situation

I've been working on a script that should copy .txt files containing specific words and with an age of 7 days maximum into a folder, once. So far I've only been able to get code to copy files to the destination folder if the file doesn't exist already.

Code

$path = "c:\PS1\*.txt"
$Destination = "c:\PS2\"
$filter = "thisisatest"
$logfile = "C:\PS2\testlog_$(get-date -format `"MMyyyy`").txt"

#Picking files with certain words and modified within the last 7 days
Foreach($file in (Get-ChildItem $path | Where-Object {$_.name -Match $filter}))
{
If($file.LastWriteTime -gt (Get-Date).adddays(-7).date)

#Logging
    {
    function log($string, $color)
        {
        if ($Color -eq $null) {$color = "white"}
        write-host $string -foregroundcolor $color
        $string | out-file -Filepath $logfile -append
        }

#Comparing folder content and copying those not present in destination folder
Compare-Object $path $Destination -Property Name, Length | Where-Object {$_.SideIndicator -eq "=>"} | ForEach-Object {Copy-Item -Path $file.fullname -Destination $Destination -Force}

    }
log $file.fullname
}

In conclusion

I have tried finding code which would make it possible to do the following:

  1. Compare path folder content to .txt log for reoccurring names and only copy those not present in list, if a file name is present in the list, move on to next file to copy.

  2. Log only files that have just been copied in a .txt file, if log doesn't exist, create.

  3. Delete log content older than 30 days

Some of my code is probably obsolete or lacking parts, it is made up from bits and pieces I have found while looking for examples.

I know most of it is probably doable with Robocopy, but I hope it can be done in powershell,

Hope you can help me

Was it helpful?

Solution

Ok, moved parameters inside function, made the $string parameter mandatory, gave the option of specifying a logfile (it will default to the global variable $logfile, and gave the color validation so people can IntelliSense it or tab complete it. I also moved it to the beginning of the script, since that's where you usually find functions and it just made more sense to me. Also made sure that the log file isn't a folder, and that it has an extension (it adds .log if it doesn't and isn't an existing file that you're just adding to). I think I may have overdone it on the function. It's very functional, and versatile in case it's needed for another script, but its kind of overkill.

Then I looked at how files were being selected, and then filtered, and revamped things a bit. Now the Get-ChildItem (alias GCI) filters the file name against $Filter, the last write time against Get-Date -7 days, it makes sure the FullName is not in the log file, and it makes sure that it's a file, not a folder.

I also added a line to clean up old logs.

function log{
Param(
    [string]$string=$(Throw 'You must provide a string to enter into the log'), 
    $LogFile = $Global:LogFile,
    [ConsoleColor]
    $color = "white")
    If((gci $logfile -ea SilentlyContinue).psiscontainer){"Specified log file is a folder, please specify a file name.";break}
    If($logfile -notmatch "\.[^\\]*$" -and !(test-path $LogFile)){$LogFile = $LogFile + ".log"}
    write-host $string -foregroundcolor $color
    $string | out-file -Filepath $logfile -append
}

$path = "c:\PS1\*.txt"
$Destination = "c:\PS2\"
$filter = "thisisatest"
$logfile = $Destination+"testlog_$(get-date -format `"MMyyyy`").txt"
gci $Destination -filter "testlog_*.txt" |?{$_.LastWriteTime -le (get-date).AddDays(-42)}| Remove-Item -Force
$AllLogs = gc "$($Destination)testlog_*.txt"

#Picking files with certain words, was modified within the last 7 days, and not already in a logfile
Foreach($file in (Get-ChildItem $path | Where-Object {!$_.PSIsContainer -and $_.LastWriteTime -gt (Get-Date).adddays(-7) -and $AllLogs -notcontains $_.FullName -and $_.Name -inotcontains $filter}))
{

$File|?{!(Test-Path $Destination+$File.Name)}|Copy-Item -Destination $Destination

log $file.fullname
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top