PowerShellでOutlookのメールを作成する


丸々利用できるコードを見つけられなかったので、調べて、継ぎ接ぎして、何とか動くものにしました。
下書き保存するだけのコードにしてはいますが、メールに関わるものですので、利用・テストされる際は誤送信など十分ご注意ください。

お礼

コード中、COMオブジェクトの破棄する箇所は@nukie_53 さんに教わったものを使わせていただきました。
ありがとうございます。
この関数は今後もCOMがらみでは必携となりそうです。

コード

outlookが起動済みか否かによらず、動きます。
一応、outlookで他で編集中のものがない方がよいです。(あれば、保存するかどうかのメッセージが出て、outlookの終了前で止まるようですが。)

メール作成して下書き保存
# すでにプロセスが存在するか調べる。
$TEST =Get-Process|Where-Object {$_.Name -match "OUTLOOK"}
if ($TEST -eq $null){
    $existsOutlook = $false
}else{
    $existsOutlook = $true
    }

# プロセスを起動または取得。PowerShellを管理者実行してると,普通に開いたオブジェクトを取ることが出来ない.
if ($existsOutlook) {
    $OutlookObj = [System.Runtime.InteropServices.Marshal]::GetActiveObject("Outlook.Application")
} else {
    $OutlookObj = New-Object -ComObject Outlook.Application
    }

#新規メールの作成。定数OlItemTypeの中身を渡す。0がメールで1が予定。あとは知らない・・・。
$mail=$OutlookObj.CreateItem(0)
#内容入力
$mail.Subject ="お暇なら来てよね"
$mail.Body ="来たら話します"
#表示は連絡帳によらず「Aさん」、「Bさん」となるはず。
$mail.To ="Aさん<[email protected]>"+"; "+"Bさん<[email protected]>"

#添付するファイルの検索、添付。繰り返せば、添付ファイルが増える仕様。
$Attach_A =Get-ChildItem C:\Users\Public\Documents | ? {$_.Name -match "value.txt$"}
$mail.Attachments.Add($Attach_A.FullName)|Out-Null
$mail.Close(0)

#***********いみひとさん(@nukie_53)より*********************************
function Disconnect-ComObject{
    param(
        [Parameter(ValueFromPipeLine =$true)]
        [ref]$inputObject
    )    
    if ($inputObject.Value -is [System.__ComObject]){

        [System.Runtime.Interopservices.Marshal]::ReleaseComObject($inputObject.Value)|Out-Null
        $inputobject = $null
        [System.GC]::Collect()
        [System.GC]::WaitForPendingFinalizers()
        [System.GC]::Collect()
    }
}
#*********************************************************

#以下、COMオブジェクトの破棄を実行。ref型にして渡す。
[ref]$mail | Disconnect-ComObject
#当初プロセスがない場合、メールを閉じたらもう何も開いていない状態になるためか、quitメソッドでエラーが出る。それを回避。
if ($existsOutlook) {$OutlookObj.Quit()}
[ref]$OutlookObj |Disconnect-ComObject

参考サイト

outlook

.NET

PowerShell

感想など

ref型

これを使えば、スコープを超えて、参照元を操作できるのですね。下記のような具合。

ref型の実験
$a =123
function testref{
    param([ref]$InputA)
    $InputA.Value =456
}
testref([ref]$a)
$a
###456が返る

連絡帳から引っ張ってくる方法

これが分からなかったのが、心残り。
VBAではMailItem.Recepients.Addなる記法が通るのですが、PowerShellではインテリセンスが効かなかったので、諦めました。

宛先を複数にする場合の記法

実験して上手く行っただけなので、もっといい記法はあるかもしれません。

発展性

Excelファイル等から宛先と呼称を二次配列に入れて、それを宛先の文字列として組み立てるというところまでやるのが本来なんでしょうね。
当座はそこまで要らなかったので、ベタ打ちにしています。

テストした環境

Windows7
Office365のOutlook(バージョン1911)
PowerShell 5.1