ディレクトリ同期のセットアップエラー

最近、環境によってディレクトリ同期のセットアップが「Microsoft Online ServicesサインインアシスタントサービスのインストールによりFAILが返されました」というエラーで失敗するようになりました。

1638のエラーコードで調べても詳細が分からなかったので、状況から考えまてみます。

  • 2ヶ月前に同じ手順でインストールした際は出なかった。
  • サインインアシスタントは既にADFSのセットアップ時にインストールしている。

…バージョンがクサいですかね?

他のサーバからディレクトリ同意ツールのセットアップ時に自動インストールあれるバージョンは7250.4285.0ということがわかります。

対して、現在インストールされていたサインインアシスタントのバージョンを確認したところ7250.4287.0と少し新しい状態でした。というわけで、一度Micrsoft Online Services Sign-in Assistantをアンインストールしてから、再度ディレクトリ同期ツールをセットアップしたところ、無事インストール完了できました。

と言うわけで、Windows PowerShell 用 Microsoft Online Services モジュールやADFSなど、先にサインインアシスタントをインストールした場合はご注意頂ければと思います。(ちなみに、4285から4287はWindows Updateで表示されますが、インストール不要と出ます。)

BlackBerry Business Cloud Servicesリリース

正式リリースから少し時間が経ってしまいましたが、BlackBerryでOffice365を利用するためのRIM社のサービスが、ようやく正式リリースされましたので、早速設定してみました。

まず、管理者権限でOffice365のポータルにログインし、右側のリソースメニュー中の【携帯電話の電子メールを設定する】を選択し、【BlackBerry Business Cloud servicesの有効化】をクリックします。
 

その後、サービスに関する情報が表示されますので、確認後「はい」にチェックを入れ、OKをクリックすると、管理者トップメニューが変更になり、下部にBlackBerry Business Cloud Servicesのメニューが表示されるようになります。【管理】をクリックして、BlackBerry Business Cloud Servicesのセットアップに移ります。
 

【今すぐサインアップ】を選択し、言語を選択すると、ソフトウェア使用許諾が表示されますので、最後まで確認した後に、同意するにチェックを入れ【続行】をクリックします。
   

これで、BlackBerry Administration Serviceにログインできるようになります。

※この時点で、自動的にBlackBerryを利用するユーザのグループと、システムアカウントへのExchange管理権限が設定されるとのことですが、うまく動作していないように見える場合は、KB28963(RIM)を参照頂き、手動で設定を確認ください。私の検証環境だと試験したタイミングが早すぎたのかもしれませんが、New-ManagementRoleAssignmentの手動実施が必要でした。

ユーザがBlackBerryを利用するには、①ユーザの登録 ②アクティベーション(端末への紐付け)が必要です。設定方法は、上記の管理画面から、【ユーザーを作成】で実施します。Exchange OnlineのGALに対して検索をかけて、そこから登録が可能です。
 

通常、ユーザーは、ユーザIDとアクティベーションパスワードを利用して端末を紐付けします。ここでは、「①管理者が指定したパスワードを設定」「②ランダムパスワードを設定し、メールで送信」「③パスワードなしで作成」が有ります。セキュリティの問題から①か②が、良いと思われます。

検証したところ、作成されたアクティベーションパスワードを利用して実際にアクティベーションができるようになるまで15~30分程度かかることがございました。また、5回失敗するとそのアカウントはロックされます。

このため、上記②でユーザに直接パスワードを飛ばしてしまうと、ユーザが届いたメールを見てすぐに登録を試行→アカウントロック→管理者がパスワードリセットが必要という流れになる可能性がございます。
→可能であれば①で管理者が指定し、1時間程度待ってからユーザに告知というのを推奨します。

小規模な組織であればパスワードを利用するのではなく、この管理画面を表示させているシステム管理者のPCにUSBでBlackBerryを接続してアクティベーションするというのが確実かもしれません。

この作業により、BlackbBerry端末からメール・予定表・連絡帳について利用出来るようになります。また、管理者サイトからExchange ActiveSyncのデバイス(Android等)同様にパスワード強制などのポリシー、リモートワイプがかけられます。その他には、「パスワードを変更してロック」「会社用のデータのみリモートワイプ」という細かい選択が可能です。

また、手順を見てお気づきの方もいらっしゃるかもしれませんが、端末はOffice365に接続するのにID/PASSは必要としません。細かい仕組みについては開示されてませんが、設定内容を見る限り、以下の様な流れで管理アカウントで代行取得をしている物と推察されます。

これに関しては善し悪しだと思うのですが、例えばADFS環境で利用している際に、ADFSやADの障害があってOutlookやOWAの認証が出来なくなったとしても、BlackBerry端末からはその影響を受けずに利用の継続が可能となっているという事かと認識してます。

ということで、他のスマートフォンとは認証プロセスと利用アカウントの運用の部分が異なるという特性を活かしつつ、上手く利用するのが良いかなと思います。

ADFSアクセス制御でのOR条件

Office365のアクセス制御を行なうクレームルールですが、サンプルで記載されているルールを参考に実装をしていくと、少し記載が難しいルールがあることに気がつきます。

それは、ルールの中に「OR条件」を入れられないことです。

例えば、許可する条件が

  • ADFS Proxy経由ではない
  • Active Syncプロトコルによるアクセス
  • Exchange Onlineに接続するグローバルIPが①

を記載する場合、サンプルでは

  • 全てのユーザーを許可
  • 「Proxy経由のアクセス」かつ「プロトコルがActiveSync以外」かつ「Exchange Onlineへの接続元が①以外」のアクセスを拒否

という記述方法を取っています。

ここで、企業内で拠点ごとにインターネットを利用している場合など、IPアドレスの接続元が複数あることはよくあることです。

また、POP/IMAPのプロトコルをアクセス制御する場合、特定条件のユーザにおいて、IPアドレスの送信元がユーザのIP帯ではなくExchange OnlineのIP帯になってくるので、そちらも許可しないといけないという仕様もございます(当該ユーザのCAS/MBX収容のDCロケーションが分かれてしまった場合に発生するらしいです)。

この場合、上記例でいう許可したいIPが追加されて、「①」から「①または②」に変更しようとして

  • 全てのユーザーを許可
  • 「Proxy経由のアクセス」かつ「プロトコルがActiveSync以外」かつ「Exchange Onlineへの接続元が①または②以外を拒否」

という正規表現内でOR条件を記載した場合、エラーが出てしまい記述できません。

また、例えば許可ルールが

  • 社内からは許可
  • ActiveSyncの外部アクセスはActiveSync_External_Accessグループのメンバのみ許可
  • Outlookの外部アクセスはMAPI_External_Accessグループのメンバのみ許可

を記載しようとした場合、

  • 全てのユーザーを許可
  • 「ActiveSync」かつ「ActiveSync_External_Accessグループ以外のアクセス」または「プロトコルがMAPI」かつ「MAPI_External_Accessグループ以外のアクセス」は拒否

などを記載できれば良いのですが、「&&」は記載できますが「||」という条件のOR記述はできません。

ということで、こういった場合は最初の全許可のルールを削除して、複数個の許可ルールを記載することにより対応できます。今回は、例として以下のサンプルをADFSに登録してみたいと思います。

  1. イントラネットからのADFS Proxyを利用しないアクセスは許可
  2. ActiveSyncは許可
  3. xxx.xxx.xxx.xxxまたはyyy.yyy.yyy.yyyのIPからのアクセスは許可
  4. MAPI_External_Accessグループの外部からのOutlookアクセスは許可
  5. それ以外のアクセスは拒否

承認する為の条件はpermitのクレームが発行され、かつdenyのクレームが発行されていないということになります。また、permitのクレームが複数発行されても動作上は問題ありませんので、デフォルトのルール(全てのユーザーを許可)を削除し、新しく個別に特定条件下にのみpermitのクレームを発行するルールを作成してみることにします。

まず、4)の準備として既存のクレームルールをバックアップしておきます。また、セキュリティグループの制御用に渡されてくる情報はグループ名ではなくSIDなので、そちらも事前に調べておきます。

【ADFSサーバ:PowerShellから実行】

Add-PSSnapin Microsoft.Adfs.PowerShell
(Get-ADFSRelyingPartyTrust -Name "Microsoft Office 365 Identity Platform").IssuanceAuthorizationRules > c:adfs_claim.bak

【ドメインコントローラ:Windows PowerShell用のActive Directoryモジュールから実行】

(Get-ADGroup "MAPI_External_Access").SID.Value

-> S1-2-34-1234567890-1234567890-1234567890-123 であったと仮定します。

そして、ADFSサーバで、PowerShellで以下のコマンドを実行して

$NewRule = @"
@RuleName = "1) accept Internal access to Office365"
NOT exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-proxy"])
 => issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");

@RuleName = "2) accept Exchange ActiveSync access to Office365"
exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application", Value == "Microsoft.Exchange.ActiveSync"])
 => issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");

@RuleName = "3) accept customer specified IP address to Office365 #1"
exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip", Value =~ "xxx.xxx.xxx.xxx"])
 => issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");

@RuleName = "3) accept customer specified IP address to Office365 #2"
exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-forwarded-client-ip", Value =~ "yyy.yyy.yyy.yyy"])
 => issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");

@RuleName = "4) accept customer specified member to Office365 by MAPI#1"
exists([Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "S-1-2-34-1234567890-1234567890-1234567890-1234"])
&& exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application", Value == "Microsoft.Exchange.Autodiscover"])
 => issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");

@RuleName = "4) accept customer specified member to Office365 by MAPI#2"
exists([Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "S-1-2-34-1234567890-1234567890-1234567890-1234"])
&& exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application", Value == "Microsoft.Exchange.OfflineAddressBook"])
 => issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");

@RuleName = "4) accept customer specified member to Office365 by MAPI#3"
exists([Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "S-1-2-34-1234567890-1234567890-1234567890-1234"])
&& exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application", Value == "Microsoft.Exchange.RPC"])
 => issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");

@RuleName = "4) accept customer specified member to Office365 by MAPI#4"
exists([Type == "http://schemas.microsoft.com/ws/2008/06/identity/claims/groupsid", Value =~ "S-1-2-34-1234567890-1234567890-1234567890-1234"])
&& exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-client-application", Value == "Microsoft.Exchange.WebServices"])
 => issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");
"@

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

※Rule3 IPアドレスのマッチングは==ではなく、=~で記載します。(同じIPアドレスが複数個渡されてくる場合がある。)
※Rule4 OutlookはMAPI(=RPC)だけではなく、4種類のプロトコルで動作するため、全て記載する必要があります。

また、前提条件の解釈によりますが、本ルールで許容されない通信があります。それは、ホワイトリストのIP帯からのWebによるアクセスになります。これは、例えば「物理的にyyy.yyy.yyy.yyyが別AD組織である場合」「クライアントPCのDNSが外部DNSを参照している場合」などで、ADFS Proxyに対してPassiveフェデレーションを行なう場合に発生します。

この際、ADFS ProxyからADFSサーバにx-ms-proxyの属性は付与されますが、x-ms-forwarded-client-ipの値は渡されてきません。(同値は、あくまでExchange Onlineから折り返してアクセスする際の元のIPアドレスなので) このため、もしこのアクセス制御を実装しようとすると、クレームルールだけでは実装できず、IISのIP制限を組み合わせて実装する必要があります。

  1. ADFS ProxyサーバのIISで、指定IP以外は拒否するIP制限を実装。この際、Exchange OnlineのIP帯を許可リストに加えることを忘れないこと。
  2. ADFSサーバでADFS Proxy経由のWebアクセスを許容するクレームルール作成
@RuleName = "accept Web access to Office365"
exists([Type == "http://schemas.microsoft.com/2012/01/requestcontext/claims/x-ms-endpoint-absolute-path"])
=> issue(Type = "http://schemas.microsoft.com/authorization/claims/permit", Value = "true");

色々あって面倒かもしれませんが、アクセス必要なパターン数はそれほど多くないと思いますので、検証しながら進めていこうかなと思ってます。

「ADFSでこんなアクセス制御はできる?」とかリクエストがあったらコメント頂ければ頑張ってみます。

Office365自習書(ADFS)が公開されました

今年に入ってから、Microsoftより人気の自習書コンテンツとして、 Office365自習書AD FS によるシングルサインオン環境構築ステップバイステップガイド が公開されました。早速拝見させて頂きましたが、非常に参考になりました。

これからOffice365のシングルサインオン環境を構築しようという方には、是非ご覧頂いて一度実際に触ってみて頂くのが良いかなと思うのですが、少しだけOffice365側の仕様変更に伴ってこの手順からの差分が出てしまっているところがあり、躓いてしまう可能性がありますので、簡単に纏めさせて頂きたいと思います。

  1. ADFSのWindows Server 2008(無印)上でのセットアップが難しくなりました。
    • 特に事情が無い場合、Windows Server 2008 R2上へのセットアップを推奨します。
    • AD FSサーバのインストール時のフェデレーションドメインの設定に必要なツールが「フェデレーション構成ツール」から「Office 365 用 Windows PowerShell コマンドレット」に統合されました。
    • 上記コマンドレットの要件がWin7/2008R2のため、シングルサインオン用にドメインを構成する工程を別のコンピュータから実行する必要があります。
    • AD FS ProxyならびにAD FSファームの2台目以降などのインストールには影響有りません。
  2. [5.1]ディレクトリ同期のデフォルト時のオブジェクト数制限が10000から20000に緩和されました。
    • 20000を越える場合は解除する数を指定の上、サービスリクエストを上げて数を緩和する必要があります。
    • サービスリクエストの処理には時間が掛かりますので、ディレクトリ同期ツールのインストールする1週間前にはOffice365を開通させ、リクエストを出しましょう。
  3. [9.3]ドメインの所有確認 で独自ドメイン追加後の表示が”確認済み”に変更になりました。
    • 7で「追加したドメインの状態が”アクティブ”になっていることを確認します」となってますが、いつまで待ってもアクティブにはなりません。(昨年途中から表示が「確認済み」に変わってます。)

説明の記述が誤っていて訂正したいなと思っているところが有ったり、企業向けに必須な機能である「アクセス制御」の機能を実現するために必要なAD FS 2.0 RU1についても是非取り込んだ形で、何か簡単な物でも作って公開していきたいと思います。

#今の自習書ベースに直すなら簡単ですが、MSさんの著作物なので勝手に改変する訳にもいかないですしね…

Microsoft Online Serviceモジュールの更新

気づくと年が明けてもう1月後半です。本業の方の忙しさにかまけて更新サボってしまってしまっておりました、いけないですね。気を取り直して今年の初投稿です。

久しぶりにPowerShellでOffice365(Exchange Onlineではなく)に接続したところ、以下の様なメッセージが表示されるようになりました。

何やら、モジュールが新しくなったのでポータルからダウンロードしろということ。早速ポータルからAdministrationconfig-ja.msi をダウンロードして実行してみます。

アンインストールしてからインストールとのこと。開いているPowerShellウィンドウを閉じてアンインストールを実行します。再起動は必要有りませんでした。そして、もう一度インストーラーを実行すると無事にインストールが完了します。

エラーも表示されなくなりました。

何が変わったのかと調べてみると、これかな?というのがTechNetに詳細がありました。

Microsoft Online Services – 2011 年 12 月の新機能
http://technet.microsoft.com/ja-jp/library/hh771296.aspx

どうやら、

  • Get-MSOnlineUser
  • Set-MSOnlineUserPassword

の2つのコマンドが追加されたとのこと。早速試したところ、そんなコマンドは無いと怒られてしまいます。

もう一度TechNetで確認したところ Online Services – Business Productivity Online とのこと。これはBPOSに関する更新のことっぽいですね。

ということで、何が変わったかは調査中なのですが、とりあえず警告メッセージは出なくなったので良しとしますか。

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を上げても送受信サイズの変更はサービスに至っていないと言われます。)

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

Lync Online構成用のDNSレコードの変更

Lync Onlineのバージョンアップに伴い、独自ドメイン環境でOffice365を利用する場合に利用するDNSレコードが変更になったようです。

管理者メニューのドメインの所から参照すると、現在以下の様な感じになっています。

SRVレコードで_SIPというサービス名が必要だったのが無くなり、代わりにCNAMEレコードを利用した記載に変わっていますね。

あと、lyncdiscoverというCNAMEレコードが加わってます。こちらはLyncMobileへの対応用でしょうか。

ちなみに、プランPでDNSをMicrosoftにホスティングされている方(通常はこちらのパターンだと思います)については、自動的に切り替わっていますので心配されることはございません。

特に表立ってレコード変更をかけてくれというアナウンスは無かったので、何もDNSいじっていなかったのですが、問題は発生していません。気になったので、Lyncクライアント側での動作をパケットキャプチャして見てみることにします。

どうやら、先にSRVレコードで_sipのサービス名を引きに行き、それが無かった場合にsip.[domain name]のレコードをクエリしている様です。
※その他、sipinternalというレコードも見ているようです。

確かに、インターネットに接続している外部向けDNSでSRVレコードを利用するというのはあまり聞きませんし、対応しているDNSホスティングサービスも非常に少数なので、サービスとしては良い方向性に向かっているのだと思います。現状のユーザーへの影響度も少なくなるように考慮はされているのでしょう。

ユーザ側の立場からしてみるとどんどんバージョンが上がって良い物になっていくというのはクラウドサービスの良いところではありますが、システム管理者やSIerの立場からすると、その内容やタイミング含め自分の制御下で実施出来ないということは煩わしさも感じてしまう面も存在します。

いずれこなれてきて、こういった類の情報のクラウド事業者→利用者への伝達手段も洗練されたものになってくると良いですね。

ソフトマッチについて試してみた

「ソフトマッチ」と聞いても、なかなかピンとこない方も多いのでは無いかと思います。これは、
先にOffice365にメールボックスが作成されているクラウドIDのアカウントに対して、後からオンプレミスのActive Directoryの同期アカウントとして紐付ける
手法です。

非サポートの手法と言われていて、仕様がいつ変わるかも分からない物だったのですが、どうやらそろそろ正式にサポートされるかも…という話を聞いたので少し検証してみます。

まず、ディレクトリ同期について、通常のフローで言うと以下の様なデータの流れになります。

  1. オンプレミスのActive Directoryのアカウント情報がディレクトリ同期によってOffice365のADに同期アカウントとして作成される。同期アカウントはOffice365側では編集不可。
  2. Office365側では、独自に作成したオンプレとは非同期のアカウントも作成可能。
  3. Exchange Onlineのサブスクリプションを付与することにより、メールボックスが作成される。
    ※Exchange Online側で先に作成されてOffice365に同期されるパターンも有り

この時、Office365上では同期アカウントと非同期アカウントがありますが、それぞれの区分を変更したりすることはできません。同期アカウントに対してはSourceAnchor(オンプレのオブジェクトのGUIDから生成)という値が保持され、これがあるかどうかで同期アカウントか判断されます。またこれにより、ディレクトリ同期サーバを再インストールしても連携が保持されます。

ここで、ケースによっては、ディレクトリ同期ツールでアカウントを作成するのが難しいことがあります。例えば、

  • 移行に合わせてフォレスト統合を行う必要があるが、Office365の利用希望日に間に合わなく先にクラウドIDを利用して開通させたい。また、統合後はメールボックスは保持したまま移行したい。
  • Office365を利用開始後、パスワード管理やアクセス制御などの問題でADFS導入を行いたい。
  • ディレクトリ同期されたアカウントのメールボックスの復活を行い、再び同期アカウントに紐付けたい。(削除済みメールボックスの回復は、非同期アカウントの新規作成と合わせた紐付けとなる)
  • BPOSの移行されてきたメールボックスをADFS環境で利用したい。

などです。最後の項目があるのでサポートせざるを得ないだろうという話なんでしょうね。ここで解決法として登場してくるのがソフトマッチです。(※ちなみに、上記で記載したSourceAnchorによるマッチングは「ハードマッチ」と呼ばれます。)

ディレクトリ同期ツールからしてみると、新規でアカウントを作成しようとしますが、Office365側のアカウント作成プロセスにおいて条件をチェックし、「新規作成」から「変更(SourceAnchor含む)」に勝手に変更してくれるという形になります。

つまり、先にディレクトリ同期されてOffice365側に対応する同期アカウントが出来ていて、後から属性の変更などで条件を満たすようになったとしても、このマッチングは行われません。(というか、属性の一意性エラーで同期ツールによる変更が実施されません。)

ここでの特定条件のマッチングですが、以前はUPNとメールアドレスの完全一致とか言われてましたが、どうやら今はメールアドレスだけで判定されているという話なので、いくつかパターン見て調べてみます。

  1. UserPrincipalName、mail、ProxyAddresses(SMTP:で始まるプライマリ)が完全一致…OK
  2. UserPrincipalName、ProxyAddresses(SMTP)が完全一致…OK
  3. mail、ProxyAddresses(SMTP)が完全一致…OK
  4. ProxyAddresses(SMTP)が完全一致…OK
  5. ProxyAddresses(smtp)がOffice365側の追加アドレスに一致(smtp:で始まる)…OK
  6. mailがOffice365側のプライマリアドレスに一致…OK
  7. mailがOffice365側の追加アドレスに一致…OK
  8. 一度同期されたオブジェクトを Explicit Disconnector にする手法を使ってOffice365から消して、mail属性を追加アドレスと一致させてから再同期…OK

Office365側に作成済みのアカウントのメールアドレス(mail、ProxyAddresses(SMTP:)、ProxyAddresses(smtp:))のいずれか1つでも等しいADのオブジェクトが、ディレクトリ同期でOffice365側に同期され、アカウントの新規作成が実施されようとした際にソフトマッチが行われるようです。

ただ、1点注意事項。8番で実験しましたが、一度ソフトマッチに失敗しても、オンプレ側のADを削除することなくリカバリをすることは可能です。逆に、一度でもソフトマッチで同期オブジェクトになってしまった場合は元には戻せません。Office365側にオンプレと同じsourceAnchorが付与されて、ハードマッチの状態になってしまうからです。(まあ、SR上げて気長に1週間くらい待てば可能かもですが)

一度同期されればハードマッチ状態になりますので、気を遣わなくてはいけないのは一度だけです。また、現時点ではいつ仕様が変わるか分からないので、直前に検証(仕様が変わっていないか)は必要かと思いますが、上手く使いこなせれば展開方法の柔軟性が格段に増すかと思います。

簡単に手順を記載します。同期アカウント(contoso-jp.com)と非同期アカウント(fabrikam-jp.com)の混在環境が合ったとします。

ここで、fabrikam-jp.comのユーザがcontoso-jp.comへのフォレスト統合が完了したとして、contoso-jpのアカウントを保持したと仮定します。

ここで、ディレクトリ同期が走る前に電子メール(mail)属性をマッチングさせたいOffice365側のメールアドレスと一致させます。

手動同期を実施すると、

ソフトマッチによりfabrikam01のアカウントが同期アカウントに変更されます。

ここで注意点ですが、シングルサインオン(ADFS)として構成している場合は問題ないのですが、ディレクトリ同期のみで実装している場合、ユーザのログオンアカウント名(UserPrincipalName)についてはオンプレミスでの変更はOffice365側に同期されません。整合性を取るため、mail属性だけではなく、UPN名についても一致した状態でソフトマッチさせることを推奨いたします。

上記例の場合は、先にOffice365側でfabrikam01@fabrikam-jp.comからfabrikam01@contoso-jp.comにユーザ名を変更してからソフトマッチするということになります。。

今後のMicrosoft側の発表についても、ウォッチしたいと思います。