SOLVED

Copy a file and send that copy via email on a loop

Copper Contributor

Hi, I was just wondering if there is a way to copy a .txt file to a specific destination and then send that copy via email on a loop that runs every hour or so? I've tried to do it but have had no luck.

10 Replies
And what do you have so far? You can copy files using copy-item and send an email using send-mailmessage with an attachment that contains that file. You can use a Task Schedule to run the script every hour or only once running a while ($true) {script contents with a start-sleep -seconds 3600} in it?
So I’m very new to Powershell, so what I did was run a script that would copy the file to another file every so often. And I ran another instance of powershell that emailed that copy every so often. But they won’t run at the same time. If the copy script is running the email script won’t work. Is there a way I can have both of those tasks run in one script? Again I’m very new to powershell which is probably why I’m having such a hard time with this.

@PandaPoodle 

 

You could try something like

while ($true) {
#Copying file to other location
Copy-Item -Path c:\temp\filename.txt -Destination d:\backup -Force:$true

#Sending mail with the file
Send-MailMessage -SmtpServer smtp.domain.local -port 25 -Subject "Emailing the file" -Body  "See attached file" -Attachments d:\backup\filename.txt -To "Email address removed" -From "Email address removed"

#Wait for 1 hour
Start-Sleep -Seconds 3600
}
And you can schedule this and keep it running forever 🙂 Did this work for you?

It works with one loop but whenever it loops again it doesn't copy the file again. Instead I get an error stating that the Copy-Item cannot access the d:\backup file because its being used by another process. This only happens if I use the email script.

It takes a few seconds to copy and email the file and then you have like an hour of editing time but.. I can imagine if it's in use or locked, that the copy-item could give an error.. But I tested it having a .csv file open in Excel and I can copy the file without issues..

Could you elaborate on "it crashes"? Does the Scheduled Task stop running?
The Task continues to run but when it gets to the Copy-Item part that errors out and it just contunes onto the email part of the script.
best response confirmed by PandaPoodle (Copper Contributor)
Solution

@PandaPoodle 

 

Some error handling and checking 🙂 

 

function Test-FileLock {
    param (
        [parameter(Mandatory = $true)][string]$Path
    )
  
    $oFile = New-Object System.IO.FileInfo $Path
  
    if ((Test-Path -Path $Path) -eq $false) {
        return $false
    }
  
    try {
        $oStream = $oFile.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
  
        if ($oStream) {
            $oStream.Close()
        }
        $false
    }
    catch {
        # file is locked by a process.
        return $true
    }
}
  
  
while ($true) {
    #Copying file to other location but checking if it's in use first
    if ((Test-Filelock -path d:\backup\filename.txt) -eq $False) {
        Copy-Item -Path c:\temp\filename.txt -Destination d:\backup -Force:$true
  
        #Sending mail with the file
        Send-MailMessage -SmtpServer smtp.domain.local -port 25 -Subject "Emailing the file" -Body  "See attached file" -Attachments d:\backup\filename.txt -To "Email address removed" -From "Email address removed"
    }
  
    #Wait for 1 hour
    Start-Sleep -Seconds 3600
}

That works great! Thank you so much for all your help!!

No problem and please mark my answer as solution 😊
1 best response

Accepted Solutions
best response confirmed by PandaPoodle (Copper Contributor)
Solution

@PandaPoodle 

 

Some error handling and checking 🙂 

 

function Test-FileLock {
    param (
        [parameter(Mandatory = $true)][string]$Path
    )
  
    $oFile = New-Object System.IO.FileInfo $Path
  
    if ((Test-Path -Path $Path) -eq $false) {
        return $false
    }
  
    try {
        $oStream = $oFile.Open([System.IO.FileMode]::Open, [System.IO.FileAccess]::ReadWrite, [System.IO.FileShare]::None)
  
        if ($oStream) {
            $oStream.Close()
        }
        $false
    }
    catch {
        # file is locked by a process.
        return $true
    }
}
  
  
while ($true) {
    #Copying file to other location but checking if it's in use first
    if ((Test-Filelock -path d:\backup\filename.txt) -eq $False) {
        Copy-Item -Path c:\temp\filename.txt -Destination d:\backup -Force:$true
  
        #Sending mail with the file
        Send-MailMessage -SmtpServer smtp.domain.local -port 25 -Subject "Emailing the file" -Body  "See attached file" -Attachments d:\backup\filename.txt -To "Email address removed" -From "Email address removed"
    }
  
    #Wait for 1 hour
    Start-Sleep -Seconds 3600
}

View solution in original post