Office365シングルサインオン設定手順(RU1対応)

AD FS 2.0 Rollup1の設定について、あまり詳しく説明しているドキュメントが見つからなかったので自分で手順を作成してみました。

なお、AD FS2.0のインストールならびにOffice365の設定はすでに完了しているものとして作成をしております。

Webのガイドに記載されているGUIでの手順は、プルダウンで選ぶメニューのところに直接値を入力するという物で、確かに登録はできるのですが、手順上も最終的な見た目もあまり綺麗ではないので、今回は別の方法を取ることにしたいと思います。
 

少し設定項目が多く、GUIからの設定は面倒なのでPowerShellから実施したいと思います。AD FSがセットアップされたマシンでPowerShellスナップインを自動的に読み込むようにプロファイルを作成します(安納さんのblogで丁寧に説明してます:【IDM】AD FS 2.0 PowerShell コマンドレットを使用する~1 基礎編)。

if ((Test-Path (Split-Path $Profile)) -eq $False) { md (Split-Path $Profile) }
Echo "Add-PSSnapin Microsoft.Adfs.PowerShell" >> $Profile
Set-ExecutionPolicy RemoteSigned

再度PowerShellを起動すると、AD FS関係のコマンドレットが利用できるようになります。

まずは、手順では必須とされておりませんが、要求記述に名前を登録します。ここで登録した名前を、クレームルールのテンプレートなどで利用することができますので、可読性が向上するかもしれません。

Add-ADFSClaimDescription -Name "Exchange送信元IP" -IsAccepted $True -IsOffered $True -IsRequired $False -Notes "Exchange Onlineへの接続元グローバルIP" -ClaimType "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip"
Add-ADFSClaimDescription -Name "Exchangeクライアントプロトコル" -IsAccepted $True -IsOffered $True -IsRequired $False -Notes "Exchange Onlineへの接続プロトコル" -ClaimType "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application"
Add-ADFSClaimDescription -Name "ExchangeクライアントUserAgent" -IsAccepted $True -IsOffered $True -IsRequired $False -Notes "Exchange Onlineへの接続エージェント" -ClaimType "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-user-agent"
Add-ADFSClaimDescription -Name "ADFS Proxy利用" -IsAccepted $True -IsOffered $True -IsRequired $False -Notes "ADFS Proxyの利用有無の判定" -ClaimType "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy"
Add-ADFSClaimDescription -Name "ADFS Proxy絶対パス" -IsAccepted $True -IsOffered $True -IsRequired $False -Notes "ADFS Proxyの絶対パス(Active/Passive)" -ClaimType "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path"

これで要求記述に以下のように登録されます。

続いて、要求プロバイダー信頼から受け付け変換規則を作成します。とはいっても、単にパススルーするだけの簡単なルールです。

$NewRule = (Get-ADFSClaimsProviderTrust).AcceptanceTransformRules
$NewRule = $NewRule + @"
@RuleTemplete = "PassThroughClaims"
@RuleName = "[ADFS2.0 RU1] すべての Exchange送信元IP 要求のパス スルー"
c:[Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip"]
 => issue(claim = c);
`r
@RuleTemplete = "PassThroughClaims"
@RuleName = "[ADFS2.0 RU1] すべての Exchangeクライアントプロトコル 要求のパス スルー"
c:[Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application"]
 => issue(claim = c);
`r
@RuleTemplete = "PassThroughClaims"
@RuleName = "[ADFS2.0 RU1] すべての ExchangeクライアントUserAgent 要求のパス スルー"
c:[Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-user-agent"]
 => issue(claim = c);
`r
@RuleTemplete = "PassThroughClaims"
@RuleName = "[ADFS2.0 RU1] すべての ADFS Proxy利用 要求のパス スルー"
c:[Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy"]
 => issue(claim = c);
`r
@RuleTemplete = "PassThroughClaims"
@RuleName = "[ADFS2.0 RU1] すべての ADFS Proxy絶対パス 要求のパス スルー"
c:[Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path"]
 => issue(claim = c);
`r
"@

Set-ADFSClaimsProviderTrust -TargetName "Active Directory" -AcceptanceTransformRules $NewRule

これで、受け付け変換規則に、必要な属性のパススルーするルールが作成されました。(発行済み要求のところには、先ほど登録した名称が記載されています。)

最後に、発行承認規則を作成します。これは、ADFS 2.0 RU1で実装されたアクセス制御にて紹介させて頂いたとおり、各組織ごとにポリシーを決める必要がありますので、それに従って設定をします。今回は、例②の指定IP(123.123.123.123)もしくはActiveSync以外からのProxyアクセスを拒否するルールを作成してみます。

$NewRule2 = (Get-ADFSRelyingPartyTrust).IssuanceAuthorizationRules
$NewRule2 = $NewRule2 + @"
@RuleName = "block all external access to Office365, except Exchange ActiveSync"
exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy"])
&& NOT exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application", Value == "Microsoft.Exchange.ActiveSync"])
&& NOT exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip", Value =~ "123.123.123.123"])
=> issue(Type = "http://schemas.microsoft.com/authorization/claims/deny", Value = "true");
"@

Set-ADFSRelyingPartyTrust -TargetName "Microsoft Office 365 Identity Platform" -IssuanceAuthorizationRules $NewRule2

これで、Office365へのチケットの発行を制御する発行承認規則ができます。

このルールをカスタマイズすることにより、AD FSにてExchange Onlineのリッチクライアントからのアクセスを制御できるようになります。

PowerShellでOffice365の日次管理タスクを実行する

※この投稿は PowerShell Advent Calender に参加しています。

Office 365は、ポータルとExchange OnlineについてPowerShellで接続して操作を行なうことができます。

今回は、スクリプトを利用してOffice365の管理者が定期的に実行する作業を自動化して、朝コーヒー飲む時間分くらいは節約できるようにしてみたいと思います。

まずは、タスクから自動で実行して接続するために、認証情報をファイルに保存します。
(以下、admin@example.onmicrosoft.com を管理者アカウントとして想定)

$LiveCred = Get-Credential
$LiveCred.Password | ConvertFrom-SecureString | Set-Content $Env:Windiradmin_example.pass

今回はテスト用にWin直下に放り込んでますが、常用する際はちゃんとアクセス権を設定して保護して下さい(一応暗号化はされてますが)。

まずは、パスワードファイルからパスワードを読み込み、Office365管理ポータルとExchange Onlineに接続します。普段の作業用には、ここまでのショートカット作っておくと楽です。

Import-Module MSOnline
$password = Get-Content $Env:Windiradmin_example.pass | ConvertTo-SecureString
$LiveCred = New-Object System.Management.Automation.PSCredential "admin@example.onmicrosoft.com",$password
Connect-MsolService -Credential $LiveCred
$Session = New-PSSession -ConfigurationName Microsoft.Exchange -ConnectionUri https://ps.outlook.com/powershell/ -Credential $LiveCred -Authentication Basic -AllowRedirection
Import-PSSession $Session

まずはOffice365管理ポータルから、サブスクリプションの利用状況を取得します。作成すべきアウトプットによって出力先は変えればいいかと思いますが、まずはcsvファイルに日付付きで出力してみようと思います。

Get-MsolAccountSku | select @{name="名前";exp={$_.SkuPartNumber `
 -replace "DESKLESSPACK","Office365 プランK1" `
 -replace "DESKLESSWOFFPACK","Office365 プランK2" `
 -replace "LITEPACK","Office365 プランP1" `
 -replace "STANDARDPACK","Office365 プランE1" `
 -replace "STANDARDWOFFPACK","Office365 プランE2" `
 -replace "ENTERPRISEPACK","Office365 プランE3" `
 -replace "ENTERPRISEWITHSCAL","Office365 プランE4" `
 -replace "EXCHANGEENTERPRISE","Exchange プラン2" `
 -replace "EXCHANGEDESKLESS","Exchange KIOSK" `
}},`
@{name="有効";exp={$_.activeUnits}},`
@{name="期限切れ";exp={$_.SuspendedUnits}},`
@{name="割り当て済み";exp={$_.ConsumedUnits}} `
| Export-Csv -Encoding UTF8 -NoTypeInformation $env:tmpo365_subscription_$(Get-Date -Format "yyyyMMdd").csv

SkuPartNumberにそれぞれプランに対応する文字列が入っているのですが、ちょっとまだ判明していないプランが有るので分かる範囲で。

続いては、Exchange Onlineに接続してメールボックスの利用状況を見てみたいと思います。オンラインヘルプの Windows PowerShell を使用してメールボックス サイズとメールボックス クォータを表示する 辺りに詳しいサンプルがありますので、こちらを参考にします。(ただ、私の環境だとサイズの計算のところで上手く値の変換とかしてくれなくて動かなかったので、サンプルは末尾のように一部変更する必要がありました。)

まず、後からExcelで加工できるように、一度csvファイルに出力します。

Get-Mailbox -ResultSize Unlimited `
| ? {$_.RecipientTypeDetails -eq "UserMailbox"} `
| Get-MailboxStatistics `
| Export-Csv -Encoding UTF8 -NoTypeInformation $env:tmpo365_mailboxstat_$(Get-Date -Format "yyyyMMdd").csv

本当はこの時点でsortとかできると良いのですが、Office365で出力した物が、Exchange2010とかと違ってToMBとかの変換が利かないようなので、文字列を数値に変換してからソートしてます。

Import-CSV $env:tmpo365_mailboxstat_$(Get-Date -Format "yyyyMMdd").csv `
| select DisplayName,ItemCount,@{name="MailboxSize";exp={$_.TotalItemSize.Split("(")[1].Split(")")[0].Split(" ")[0].Replace(",","")}} `
| sort {[int] $_.MailboxSize} -descending `
| select DisplayName,@{name="Alias";exp={(Get-Mailbox $_.DisplayName).Alias}},@{name="Mail";exp={(Get-Mailbox $_.DisplayName).PrimarySmtpAddress}},ItemCount,MailboxSize `
| Export-Csv -Encoding UTF8 -NoTypeInformation $env:tmpo365_mailusage_$(Get-Date -Format "yyyyMMdd").csv

とりあえず、こんな感じの物を office365_daily.ps1 として保存しておきます。そして、これをタスクスケジューラーに登録します。「ユーザーがログオンしているかどうかにかかわらず実行する」「最上位の特権で実行する」を選択します。

操作では、直接ps1ファイルを指定するとメモ帳がバックグラウンドで立ち上がって終わりという悲しい事態になるので、プログラム「C:WindowsSystem32WindowsPowerShellv1.0powershell.exe」引数の追加「-Command <先ほど作成したps1ファイル>」

で、トリガーで「毎日4:02に起動」とか設定しておくと、デイリーのレポートを自動的に生成してくれます。

本当はWebページに接続して、ポータルからメンテナンス予定や故障発生レポート、FOPEから前日のトラフィックレポートなどを自動取得したり、結果をメールで送信したりするのも作りたかったのですが、認証系が少し面倒そうなので今回は軽めの所からやってみました。

【参考】オンラインヘルプのサンプルの要修正場所

すべてのメールボックスのサイズとクォータの状態を表示する

Get-Mailbox -ResultSize Unlimited | Get-MailboxStatistics | Select DisplayName,StorageLimitStatus,@{name="TotalItemSize (MB)";expression={[math]::Round(($_.TotalItemSize.Value.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)}},@{name="TotalDeletedItemSize (MB)";expression={[math]::Round(($_.TotalDeletedItemSize.Value.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)}},ItemCount,DeletedItemCount | Sort "TotalItemSize (MB)" -Descending | Export-CSV "C:My DocumentsAll Mailboxes.csv" -NoTypeInformation

メールボックス クォータを超過したメールボックスのみを表示する

Get-Mailbox -ResultSize Unlimited | Get-MailboxStatistics | where {$_.StorageLimitStatus.ToString() -ne "BelowLimit"} | Select DisplayName,StorageLimitStatus,@{name="TotalItemSize (MB)";expression={[math]::Round(($_.TotalItemSize.Value.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)}},@{name="TotalDeletedItemSize (MB)";expression={[math]::Round(($_.TotalDeletedItemSize.Value.ToString().Split("(")[1].Split(" ")[0].Replace(",","")/1MB),2)}},ItemCount,DeletedItemCount | Sort "TotalItemSize (MB)" -Descending | Export-CSV "C:My DocumentsExceeded Quotas.csv" -NoTypeInformation

ExchangeOnlineの最大送受信サイズ

Exchange Onlineですが、サービス説明書によると送受信するメールの最大サイズは現在25MBとなっています。

ちなみに、この値ですが、βテストが終わってGAを迎える際、英語版のドキュメントのみ一時的に35MBに変わっておりました。(現在は25MBに戻っています)

ただ、PowerShellで調べてみると、現在最大送信サイズ=35MB、最大受信サイズ=36MBと設定されています。(以下でadminとtestuseroneが送受信20MBな理由は後述します。)

MicrosoftにSRで確認したところ、サービス説明書の値が正しく、誤っている物は今後(時期は未定だが)修正していく予定とのこと。

今回、送受信できるサイズについて色々調べていく中で、設定されている値について何となく自分的に納得できる理由が見つかりましたので紹介します。

まず、このサイズ通りに本当に送受信が可能かどうかを見てみます。Outlook2010を利用して、①自分宛 ②同テナント内の別ユーザ宛 ③他テナント宛てのユーザに送ってみます。

①自分 ②テナント内 ③テナント外
Outlook2010 25MB添付
Outlook2010 34.5MB添付 ×(FOPEでNDR)
Thunderbird 34.5MB添付 ×(送信エラー) ×(送信エラー) ×(送信エラー)

Outlook2010(MAPI)では、添付ファイルをエンコーディングしない形で送信をするので、34.5MBの添付ファイルを付けても送受信が可能です。

ただし、自テナント外に送信をしようとした場合、Exchange外部のFOPE(アンチスパム)に送信されますが、ここでエンコードされて35MBを突破してNGになるようです。

Thunderbird(IMAP/SMTP)の場合は、そもそもExchangeに接続しに行く際に自力でエンコーディングして飛ばしてきます(というか、MUAとしてはこちらの動作の方が一般的)ので、送信を試行した段階でエラーが出ます。

エンコード後35MBなので、エンコードで増える分(約+35%)を考えると、25.9MBくらいが閾値になりそうです。試しに30MBから1MBずつ添付ファイルのサイズを減らして行ったところ、26MBの添付ファイルは送信できず、25MBのファイルは送信できました。

という訳で、きっとサービス仕様としては明示してないですが、エンコード後でも25MBを確保できるように今の設定にしているのだと思われます。

ちなみに、受信サイズが+1MBされているのは、送信不可の際のエラーを受信できるようにするためでしょう。

さて、一番最初に出ていたadminとかtestuseroneというユーザーがなぜか送受信サイズが20MBになっています。これはどんなアカウントかというと、
 「βテスト当初からメールボックスが作成されていたアカウント」
言わば率先して人柱になってくれていたユーザーであり、通常は情報システム部などのアカウントがこれになっている事が多いと思います。

メールボックスを消して再作成(削除済みメールボックスの復活)すれば、新しい送受信サイズでデプロイされますが、半年分のメールを一度消すという行為と作成・再作成の間の受信のタイムラグでメールロストしてしまう可能性を考えると結構しびれますよね。

また、フェデレーションアカウントの場合は通常だとメールボックスの復活の対応も出来ないので、八方ふさがりになってしまいます。(SRを上げても送受信サイズの変更はサービスに至っていないと言われます。)

ということで、フェデレーションアカウントの場合の対応は次回以降の宿題ということで…