Windows OS
--
Questions
--
Followers
Top Experts
Powershell Move Files In A Folder
My code below is part of a larger script that loops through files in a folder and sends an email with attachment. Â After each email, I would like the file to be moved to a new folder. Â I am getting an error that a file is in use. Â It seems to loop through all files ok, but one can never be used because it is in use. Â Short code and Error below with full code.
I have also tried putting the move command after the loop. Â It always leaves one file.
My full code is
PS C:\Users\scott> $Path = "C:\temp\"
$NewPath = "C:\temp\sent"
$files = Get-ChildItem C:\temp\*.*
ForEach ($file in $files) {
$attachment = $path+$file.name
#send mail
Move-Item $attachment $NewPath -force
}
ERRORMove-Item : The process cannot access the file because it is being used by another process.
At line:6 char:5
+ Move-Item $attachment $NewPath -force
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : WriteError: (C:\temp\test2.txt:FileInfo) [Move-Item], IOException
+ FullyQualifiedErrorId : MoveFileInfoItemIOError,Microsoft.PowerShell.Commands.MoveItemCommand
I have also tried putting the move command after the loop. Â It always leaves one file.
PS C:\Users\scott> $Path = "C:\temp\"
$NewPath = "C:\temp\sent"
$files = Get-ChildItem C:\temp\*.*
ForEach ($file in $files) {
$attachment = $path+$file.name
#send mail
}
Move-Item $attachment $NewPath -force
My full code is
$Path = "C:\temp\"
$NewPath = "C:\temp\sent"
$files = Get-ChildItem C:\temp\*.*
ForEach ($file in $files) {
$SMTPServer = "smtp.example.com"
$SMTPPort = "587"
$Username = "me@example.com"
$Password = "abc134"
$to = "you@example.com"
$subject = "Email Subject"
$body = "Insert body text here"
$attachment = $path+$file.name
$message = New-Object System.Net.Mail.MailMessage
$message.subject = $subject
$message.body = $body
$message.to.add($to)
#$message.cc.add($cc)
$message.from = $username
$message.attachments.add($attachment)
$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.send($message)
#write-host "Mail Sent"
# Move-Item $attachment $NewPath -force
}
Move-Item "C:\temp\*.*" $NewPath -force
Zero AI Policy
We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.
Always the same file, or is there any pattern?
If you think it is being locked by the mail send process, then I would insert the following at line 30.
$smtp.Dispose()
I could see how that would happen. Â You could also try throwing in a delay (Start-Sleep).
I'm curious why you're not using the Send-MailMessage cmdlet. Â Unless you're using an older version of PS, all the functionality is there.
If you think it is being locked by the mail send process, then I would insert the following at line 30.
$smtp.Dispose()
I could see how that would happen. Â You could also try throwing in a delay (Start-Sleep).
I'm curious why you're not using the Send-MailMessage cmdlet. Â Unless you're using an older version of PS, all the functionality is there.
>I'm curious why you're not using the Send-MailMessage cmdlet
Because I am not very familiar with Powershell. Â I'm open though.
Because I am not very familiar with Powershell. Â I'm open though.
the .Dispose() didn't work. I think it is because of the looping. Â When I try the first sample code with 8 lines the same thing happens.






EARN REWARDS FOR ASKING, ANSWERING, AND MORE.
Earn free swag for participating on the platform.
Actually, it might be necessary to use.
$message.Dispose()
or even just setting the attachments property to $null.
Testing would be needed to determine the impact, but some efficiency could be had by moving elements that don't change out of the foreach loop. Â Maybe just keeping the $message.attachments.add($ attachment ) and $smtp.send() bits in there.
If you've got PS 3.0+, then I'd just use Send-MailMessage. Â I think the syntax is easier.
$message.Dispose()
or even just setting the attachments property to $null.
Testing would be needed to determine the impact, but some efficiency could be had by moving elements that don't change out of the foreach loop. Â Maybe just keeping the $message.attachments.add($
If you've got PS 3.0+, then I'd just use Send-MailMessage. Â I think the syntax is easier.
If it's happening with just that sample (where a mail send isn't really happening), then something else is locking the file. Â I'd use Process Explorer or handles.exe (Sysinternals) to try to determine what.
The key was to use both!
$smtp.Dispose()
$message.Dispose()
$smtp.Dispose()
$message.Dispose()

Get a FREE t-shirt when you ask your first question.
We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.
membership
Log in or create a free account to see answer.
Signing up is free and takes 30 seconds. No credit card required.
On Windows 10, I used both $message.Dispose() and $smtp.Dispose() but on server 2008 RT it I had to only use $message.Dispose() because  $smtp.Dispose() generated an error.
Windows OS
--
Questions
--
Followers
Top Experts
This topic area includes legacy versions of Windows prior to Windows 2000: Windows 3/3.1, Windows 95 and Windows 98, plus any other Windows-related versions including Windows Mobile.