I created this tiny script to full fill a repeated request from audit. I want to expand it but ran into an issue with file creation.

This code will create the $attachment in the directory it is run from. When using ISE it stores the $attachment to the system32 folder. When run from the script repository it leaves the file in the same directory. The goal is for the file to be attached and emailed out not leaving any remnants behind. This script is used in many functions for auditing so I will be using this as a "standard" process for automating audit reports. I am very new to scripting but looking for all feedback!!

Eventually there will be multiple attachments to be added and this run weekly. Right now they are all individual scripts that are run as requested.

    #Run Cleanup for ISE Variables using Preloaded Profile
$SmtpSender = "[email protected]"
$SmtpReceiver = "[email protected]"
$SmtpSubject = "User accounts enabled-Auditonly"
$SmtpBody = "Attached is run from PDQ using script Users.enabled-Auditonly.ps1"
$Smtpservr = "smtp.mail.com"
$attachment = New-Item "Users.enabled-Auditonly$((Get-Date).ToString('MM-dd-yyyy_hh-mm-ss')).csv" -ItemType File

Get-ADuser -Filter * -Properties Name, SamAccountName,Description, Enabled | Select Name, SamAccountName,Description, Enabled |
export-csv $attachment
#Grabs the attachment from the above location and emails it out.
Send-MailMessage -Attachments $attachment -Body $SmtpBody -BodyAsHtml -From $SmtpSender -To $SmtpReceiver -Subject $SmtpSubject -SmtpServer $Smtpservr
  • \$\begingroup\$ The -Attachments parameter allows specifying the path and file names of files to be attached to the email message. For instance, $attachment = New-Item "$env:temp\Users.enabled-Auditonl… could help? \$\endgroup\$
    – JosefZ
    Commented Feb 18, 2021 at 20:02
  • \$\begingroup\$ set your $attachment variable to just the file (path and) name: $attachment = "Users.enabled-Auditonly$((Get-Date).ToString('MM-dd-yyyy_hh-mm-ss')).csv". It will be created by the Export-Csv cmdlet (where BTW I would add switch -NoTYpeInformation. You don't want to use New-Item \$\endgroup\$
    – Theo
    Commented May 15, 2021 at 14:06

1 Answer 1


Whenever possible I try to avoid creating temp files during script execution because they tend to introduce side effects and bugs related to security, permission, cleanup and duplicates.

Export-Csv creates a file but ConvertTo-Csv creates a string variable, which will allow you to avoid an intermediate file.

The Send-MailMessage cmdlet you're using takes attachments that rely on a local path, but the .Net object System.Net.Mail.MailMessage allows adding attachments from an in-memory string. There's a good example of its use on send-mailmessage-attachment-from-memory. Instead of $([System.Net.Mail.Attachment]::CreateAttachmentFromString("HELLO2", "Test2.txt")) you can use this:

$AttachmentName = "Users.enabled-Auditonly$((Get-Date).ToString('MM-dd-yyyy_hh-mm-ss')).csv"
$AttachmentContents = Get-ADuser -Filter * -Properties Name, SamAccountName,Description, Enabled | Select Name, SamAccountName,Description, Enabled | ConvertTo-Csv 

$MailAttachment = [System.Net.Mail.Attachment]::CreateAttachmentFromString($AttachmentContents,$AttachmentName)

... and pass that $MailAttachment object to the function.


Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.