Link to home
Create AccountLog in
Windows OS

Windows OS

--

Questions

--

Followers

Top Experts

Avatar of Scott Fell
Scott Fell🇺🇸

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.

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
}

Open in new window

ERROR
Move-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

Open in new window


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

Open in new window


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

Open in new window

Zero AI Policy

We believe in human intelligence. Our moderation policy strictly prohibits the use of LLM content in our Q&A threads.


Avatar of footechfootech🇺🇸

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.

Avatar of Scott FellScott Fell🇺🇸

ASKER

>I'm curious why you're not using the Send-MailMessage cmdlet

Because I am not very familiar with Powershell.  I'm open though.

Avatar of Scott FellScott Fell🇺🇸

ASKER

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.

Reward 1Reward 2Reward 3Reward 4Reward 5Reward 6

EARN REWARDS FOR ASKING, ANSWERING, AND MORE.

Earn free swag for participating on the platform.


Avatar of footechfootech🇺🇸

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.

Avatar of footechfootech🇺🇸

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.

Avatar of Scott FellScott Fell🇺🇸

ASKER

The key was to use both!
$smtp.Dispose()
$message.Dispose()

Free T-shirt

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.


ASKER CERTIFIED SOLUTION
Avatar of footechfootech🇺🇸

Link to home
membership
Log in or create a free account to see answer.
Signing up is free and takes 30 seconds. No credit card required.
Create Account

Avatar of Scott FellScott Fell🇺🇸

ASKER

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

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.