0

I have made some progress, and stuck with the attachment. Below script now sends an email but with not an attachment

$sub = "APERAK/INVRPT Report "
$to="[email protected]"
$folder = "C:\script\APERAK"
$files = Get-ChildItem "C:\script\APERAK"
$tstmp = Get-Date -UFormat "%H%M"
$dstamp = Get-Date -UFormat "%Y%m%d"
$from="[email protected]"
$smtpserver = "mail.XXXXXXXX.com"
for ($i=0; $i -lt $files.Count; $i++) {

$subject=  $sub + $dstamp #+ " " +$tstmp
$filename =  $files[$i].FullName
$abpath = $folder + $files[$i].FullName

$attachment = new-object Net.Mail.Attachment($abpath)

$body= Get-Content $filename
$SMTP = new-object Net.Mail.SmtpClient($smtpserver)
$MSG = new-object Net.Mail.MailMessage($from, $to, $subject, $body)
$MSG.attachments.add($attachment)
$SMTP.send($msg)
}

Exception calling "Add" with "1" argument(s): "Value cannot be null. Parameter name: item" At C:\GentranScripts\APERAK_REPORT_EMAIL1.ps1:22 char:21 + $MSG.attachments.add <<<< ($attachment) + CategoryInfo : NotSpecified: (:) [], MethodInvocationException + FullyQualifiedErrorId : DotNetMethodException

7
  • 3
    for some reason, the script is entering into the for loop. ... so what is the problem here ? Commented Dec 17, 2018 at 6:42
  • 1
    do you mean is NOT entering? or is entering but not sending the email? more details, please? Commented Dec 17, 2018 at 7:00
  • I dont know what the problem is, the cursor is not entering the for loop. Commented Dec 17, 2018 at 7:04
  • 2
    Are you sure "C:\Reports\APERAK" is the correct path on your server? Try to output $files.Count on its own and look at the output. Commented Dec 17, 2018 at 7:13
  • 1
    Why don't you use foreach? As I can see you do not use $i for anything beyond addressing of an array's element. Commented Dec 17, 2018 at 11:36

1 Answer 1

2

The problem is that Get-Childitem will return two types of objects. If there's just a single file, $files = Get-ChildItem "C:\Reports\APERAK" will contain a FileInfo. If there's more, it'll contain an array of FileInfo objects. Let's look at a sample case:

md foo
cd foo
set-content -Path "foo.txt" -Value ""
$files = gci
$files.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     FileInfo                                 System.IO.FileSystemInfo

set-content -Path "foo2.txt" -Value ""
$files2 = gci
$files2.GetType()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     Object[]                                 System.Array

As for a solution, wrap gci results into an array. Like so,

$files = @(Get-ChildItem "C:\Reports\APERAK")
Sign up to request clarification or add additional context in comments.

3 Comments

@chandanT Get-ChildItem "C:\Reports\APERAK" can also return DirectoryInfo objects. These are subfolders. In your loop you expect everything to be a file on which you can do an Get-Content. To make sure you only get FileInfo objects, use Get-ChildItem "C:\Reports\APERAK" -File or use Get-ChildItem "C:\Reports\APERAK" | Where-Object { -not $_.PSIsContainer } if you are on an older PowerShell version
Please note that a scalar (single) return object is only a problem in PowerShell v2. In v3+, even single objects have a .Count property (try 'foo'.Count, for instance)
I have made some progress, and stuck with the attachment.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.