Office365で動的にメールエイリアスを作る必要があったので簡単にメモ。
APIを使って変更したかったけどPowerShellからの操作しか見当たらないのでそれで対応。
Office365のアカウント
メールエイリアスを取り扱うには管理者権限が必要。
PowerShellのバージョン
テスト用のWindows7環境だとPowerShellのバージョンが2.0になっていてそのままでは動かず。
4.0にバージョンアップしてみたところ問題なかった。
PowerShell/PowerShellのバージョンを確認する方法・$PSVersionTable - Windowsと暮らす
Download Windows Management Framework 4.0 from Official Microsoft Download Center
ツールのインストール
必要なソフトウェアとして紹介されている2種をダウンロードしてインストール。
Connect to Office 365 PowerShell
- IT プロフェッショナル 用 Microsoft Online Services サインイン アシスタント RTW
- Windows PowerShell の Microsoft Azure Active Directory モジュール の 64 ビット バージョン
スクリプト実行の許可
デフォルトではインストールしたコマンドをPowerShellで実行できないらしい。
以下のコマンドで実行可能にする。ScopeはCurrentUser|Processなどがあるらしいので適切なものを選択。
Set-ExecutionPolicy RemoteSigned -Scope LocalMachine
PowerShellでのコマンド
発行する必要があるPowerShellでのコマンドは以下の通り。
# モジュールのインストール
Import-Module MSOnline
# アカウントの認証
$UserCredential = Get-Credential
Connect-MsolService -Credential $UserCredential
# office365との接続
$exchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri "https://outlook.office365.com/powershell-liveid/" -Credential $UserCredential -Authentication "Basic" -AllowRedirection
# セッション情報の保管
Import-PSSession $exchangeSession
# 作成
Invoke-Command -ScriptBlock { Set-Mailbox アカウント名 -EmailAddresses @{Add="エイリアス名"} } -Session $exchangeSession
# 削除
Invoke-Command -ScriptBlock { Set-Mailbox アカウント名 -EmailAddresses @{Remove="エイリアス名"} } -Session $exchangeSession
# 設定済みのエイリアス取得
(Invoke-Command -ScriptBlock { Get-Mailbox アカウント名 } -Session $exchangeSession).EmailAddress
MSOnlineモジュールのコピー
C#から上記コマンドを投げても Connect-MsolService が見つからないというエラーが発生する。
Claus Konrad Blog: PowerShell and C#: Can’t load MSOnline module
C:\Windows\System32\WindowsPowerShell\v1.0\Modules に入っているMSOnlineを
C:\Windows\SysWOW64\WindowsPowerShell\v1.0\Modules にコピーする必要があるらしい。
この後、PowerShellで以下のコマンドを実行。
Import-Module MSOnline
この辺りはもう少しちゃんと調査したい。
参照の追加
プロジェクトに System.Management.Automation への参照を追加。
実行
あとはさっきのコマンドをPowerShellに投げれば良い。
/// <summary>
/// エイリアスを追加する
/// </summary>
/// <param name="alias"></param>
private void CreateAliasCommand(string aliasName)
{
StringBuilder ss = new StringBuilder();
ss.AppendLine("$password = ConvertTo-SecureString \"" + AccountPassword + "\" -AsPlainText –Force");
ss.AppendLine("$credential = New-Object System.Management.Automation.PsCredential(\"" + AccountName + "\", $password)");
ss.AppendLine("$UserCredential = Get-Credential -cred $credential");
ss.AppendLine("Connect-MsolService -Credential $UserCredential");
ss.AppendLine("$exchangeSession = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri \"https://outlook.office365.com/powershell-liveid/\" -Credential $UserCredential -Authentication \"Basic\" -AllowRedirection");
ss.AppendLine("Invoke-Command -ScriptBlock { Set-Mailbox " + AccountName + " -EmailAddresses @{Add=\"" + aliasName + "\"} } -Session $exchangeSession");
ss.AppendLine("(Invoke-Command -ScriptBlock { Get-Mailbox " + AccountName + " } -Session $exchangeSession).EmailAddresses");
var results = ExecuteCommand(ss.ToString());
var emails = ExtractEmails(results);
//作成に失敗した場合は例外
if (!emails.Contains(aliasName))
{
throw new Exception("メールエイリアスの作成に失敗");
}
}
/// <summary>
/// PowerShellコマンドの実行
/// </summary>
/// <param name="commands"></param>
/// <returns>出力結果</returns>
private List<string> ExecuteCommand(string commands)
{
var result = new List<string>();
InitialSessionState iss = InitialSessionState.CreateDefault();
iss.ImportPSModule(new string[] { "MSOnline" });
using (Runspace runspace = RunspaceFactory.CreateRunspace(iss))
{
Collection<PSObject> results = null;
try
{
runspace.Open();
using (Pipeline pipeline = runspace.CreatePipeline())
{
pipeline.Commands.AddScript(commands);
results = pipeline.Invoke();
var regex = new Regex("^SMTP:(.+)$", RegexOptions.IgnoreCase);
foreach (var item in results)
{
result.Add(item.ToString());
}
}
}
finally
{
runspace.Close();
}
}
return result;
}
IISでの実行
IIS8.0 + ASP.NET5で実行すると New-PSSession でnullが返ってきた。試しに実行ユーザを管理者に変更してみると実行できることを確認した。
この環境での実行ユーザや権限等はまだ把握できていないので追加調査が必要。
~~
当初は実行ユーザにRemote Management Usersグループに所属させれば良いと勘違いしていたが違った。
デフォルトで実行されるAPPOOLのユーザに権限付与したかったが、どうにもうまくいかないので実行ユーザをLocalServiceに変更することで対応した。