[英]How can I chain Export-CSV to Send-MailMessage without having to save the CSV to disk in PowerShell?
我想以 CSV 格式通過電子郵件發送 AD 用戶列表,但我不想在發送電子郵件之前將 CSV 保存到磁盤。
這是獲取數據的代碼:
get-aduser -filter * -properties Telephonenumber |
where Telephonenumber -ne $Null |
select givenname, surname, telephonenumber |
sort surname
現在我想添加類似的內容:
| Export-Csv |
Send-MailMessage -From HelpDesk@company.com -to someone@company.com -subject "Outlook address book export" -SmtpServer EdgeTransport
無論如何在不將文件保存到文件系統的情況下將 CSV 數據作為附件添加到內存中?
上面建議/接受的答案是不正確的,不會起作用。 Send-MailMessage 的 -Body 參數需要一個字符串對象 (System.String)。 示例中創建的 $mydata 對象是一個 System.array 對象。 如果您使用它如上所示,命令將失敗。
您可以做的是創建一個文件,用 CSV 數據填充它,將其作為附件通過電子郵件發送,然后將其刪除。
使用上面的代碼,例如:
$attachment = New-Item filename.csv -ItemType file
get-aduser -filter * -properties Telephonenumber | where Telephonenumber -ne $Null | select givenname, surname, telephonenumber | sort surname | Export-Csv $attachment -NoTypeInformation
Send-MailMessage -Attachments $attachment -Body $SmtpBodyTrue -BodyAsHtml -From $SmtpSender -To $MailTo -Subject $SmtpSubject -SmtpServer $SmtpServer
Remove-Item $attachment
$attachment = $null
我知道這是一個超級老話題,但上面的答案不再正確。 您可以將內存中的對象作為附件發送,而無需先寫入文件。 您需要使用 .net 方法,但效果很好。
關鍵是 .net 方法 [System.Net.Mail.Attachment]::CreateAttachmentFromString
Send-MailMessage
的-Attachments
參數需要一組路徑,因此您必須將文件寫入磁盤的某處。
要將您的 CSV 數據作為電子郵件的正文發送,請使用convertto-csv -notypeinformation
而不是export-csv
。
$myData = get-aduser -filter * -properties Telephonenumber | where Telephonenumber -ne $Null | select givenname, surname, telephonenumber | sort surname|convertto-csv -notypeinformation
Send-MailMessage -From HelpDesk@company.com -to someone@company.com -subject "Outlook address book export" -SmtpServer EdgeTransport -body $mydata
我知道這是一篇非常古老的帖子,但我想我會在處於類似位置后提供我的意見。
下面是我編寫的用於從對象等創建 CSV 附件的基本函數。
讓它工作的主要問題之一是首先convertto-csv
輸出引號中的所有內容(我知道這已修復 PS6 +,但在使用 PS5 時沒有用。其次將 CSV 數據轉換為字符串並將其轉換為它正在轉義回車/換行的內存流,為了解決這個問題,我將[System.Environment]::NewLine
附加到 CSV 中的每一行。
Function ConvertTo-CSVEmailAttachment {
Param(
[Parameter(Mandatory=$true)]
[String]$FileName,
[Parameter(Mandatory=$true)]
[Object]$PSObject,
$Delimiter
)
If ($Delimiter -eq $null){$Delimiter = ","}
$MS = [System.IO.MemoryStream]::new()
$SW = [System.IO.StreamWriter]::new($MS)
$SW.Write([String]($PSObject | convertto-csv -NoTypeInformation -Delimiter $Delimiter | % {($_).replace('"','') + [System.Environment]::NewLine}))
$SW.Flush()
$MS.Seek(0,"Begin") | Out-Null
$CT = [System.Net.Mime.ContentType]::new()
$CT.MediaType = "text/csv"
Return [System.Net.Mail.Attachment]::new($MS,$FileName,$CT)
}
要使用它,您需要准備好您的對象,因為它們沒有考慮管道功能(正如我所說的基本功能)。
例子:
$ADList = get-aduser -filter * -properties Telephonenumber | where Telephonenumber -ne $Null | select givenname, surname, telephonenumber |sort surname
$EmailAttachment = ConvertTo-CSVEmailAttachment -FileName "ADList.CSV" -PSObject $ADList
從Send-MailMessage
需要一個字符串到文件路徑才能起作用的意義上說,其中一個答案是正確的。
但是,您可以使用 .net 庫[Net.Mail.MailMessage]
來創建電子郵件,而不是使用Send-MailMessage
:
$SMTPserver = "This.Will.Be.Your.Email.Server.Endpoint"
$from = "SomeEmailAddress@yourdomain.com"
$to = "Recipient@domain.com"
$subject = "This is the subject Line"
$emailbody = "This is the body of the email"
$mailer = new-object Net.Mail.SMTPclient($SMTPserver)
$msg = new-object Net.Mail.MailMessage($from, $to, $subject, $emailbody)
$msg.Attachments.Add($EmailAttachment) #### This uses the attachment made using the function above.
$msg.IsBodyHTML = $false
$mailer.send($msg)
無論如何,我希望這對將來處於類似情況的人有所幫助。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.