ラベル PowerShell の投稿を表示しています。 すべての投稿を表示
ラベル PowerShell の投稿を表示しています。 すべての投稿を表示

2017/05/29

JP1/AJS3環境でWindowsファイアウォールを設定する

はじめに

JP1/Automatic Job Management System 3 (JP1/AJS3)環境において、「セキュリティが強化された Windows ファイアウォール」を Windows Powershell を用いて設定する方法を紹介する。

参考: 『JP1/AJS3環境でRHEL7/CentOS7ファイアウォールを設定する

JP1/Automatic Job Management System 3 (JP1/AJS3)は、業務を自動化する製品。
詳細は、マニュアルを参照。

JP1/AJS3 を構成する主な要素には、マネージャホスト・エージェントホストがある。
マネージャホストは、エージェントホストを制御し、ジョブを実行させる。
マネージャホストは、エージェントホストの機能を含む。
このため、マネージャホスト自身にジョブを実行させることもできる。

JP1/AJS3 は、企業内ネットワーク内部で使用されることが多い。
このため、各構成要素のパーソナルファイアウォールが無効化されていても、一概に安全でないとは言えない。
しかし、無効化しない方がセキュリティ上より安全である。

Windows Serverでは、「セキュリティが強化された Windows ファイアウォール」がパーソナルファイアウォール機能を提供する。
これをGUIで設定する方法もあるが、今回はPowershellを用いて設定する。

JP1/AJS3 環境でのファイアウォール設定要件については、以下を参考にした。

ファイアウォールの設定方針

「セキュリティが強化された Windows ファイアウォール」の流儀に従い、マネージャホストおよびエージェントホストの両方で同じルールを定義し、必要に応じてルールを有効化して使うことにする。
JP1/Base、JP1/AJS3 - ManagerおよびJP1/AJS3 - Agent必要となるファイアウォールルールをグループ化し、グループ名をぞれぞれ、JP1Base、JP1AJS3-ManagerおよびJP1AJS3-Agentとする。
エージェントホストでは、JP1BaseおよびJP1AJS3-Agentに属するルールのみを有効化する。
マネージャホストでは、JP1Base、JP1AJS3-ManagerおよびJP1AJS3-Agentすべてのグループに属するルールを有効化する。
これは、前述の通り、マネージャホストがエージェントホストの機能も併せ持つためである。

なお、以下の実行例では、Powershell のリモート処理機能を用いて作業した。
このため、実行例中のコマンドプロンプトには、[ホスト名]の様にホスト名が含まれている。
マネージャホストのホスト名をmanager、エージェントホストのホスト名をagentとしている。

ルールの定義

Powershellでは、「セキュリティが強化された Windows ファイアウォール」を操作するコマンドレットが提供されている。
新規にルールを作成するためには、New-NetFirewallRuleコマンドレットを使う。
このコマンドレットをそのまま使うとコマンドが長くなるため、作業に先立って、ヘルパ関数fwrhelperを定義する。

このヘルパ関数で定義されるルールは、一旦無効化(-Enabled False)されていることに注意。
従って、定義に続いて、必要なルールのみを有効化する必要がある。

また、適用対象のプロファイルは、Public以外のDomainおよびPrivateとしている。
Publicプロファイルは、信頼性の低い接続の場合に使われるため、JP1/AJS3環境には適切でない場合が多いだろう。

ヘルパ関数fwrhelperの定義

マネージャホストおよびエージェントホストで以下の通り実行する。

[agent]: PS C:\> function fwrhelper($Group,$Name,$DisplayName,$Protocol,$LocalPort){
>>     New-NetFirewallRule -Profile Domain,Private -Action Allow -Enabled False -Direction Inbound `
>>         -Group $Group `
>>         -Name $Name `
>>         -DisplayName $DisplayName `
>>         -Protocol $Protocol `
>>         -LocalPort $LocalPort | ft
>> }
[agent]: PS C:\>

JP1/Base 用ルールの定義

JP1/Base 用のルールを定義する。
マネージャホストおよびエージェントホストで以下の通り実行する。

[agent]: PS C:\> fwrhelper JP1AJS3-Manager JP1AJS3-Agent-to-Manager 'JP1/AJS3 Agent to JP1/AJS3 Manaer' TCP @(20241,20243,20246,20301,22251)

Name                     DisplayName                       DisplayGroup    Enabled Profile         Direction Action
----                     -----------                       ------------    ------- -------         --------- ------
JP1AJS3-Agent-to-Manager JP1/AJS3 Agent to JP1/AJS3 Manaer JP1AJS3-Manager False   Domain, Private Inbound   Allow


[agent]: PS C:\> fwrhelper JP1AJS3-Agent JP1AJS3-Manager-to-Agent 'JP1/AJS3 Manager to JP1/AJS3 Aent' TCP @(20242,20247,20300,22251,23139)

Name                     DisplayName                       DisplayGroup  Enabled Profile         Direction Action
----                     -----------                       ------------  ------- -------         --------- ------
JP1AJS3-Manager-to-Agent JP1/AJS3 Manager to JP1/AJS3 Aent JP1AJS3-Agent False   Domain, Private Inbound   Allow


[agent]: PS C:\> fwrhelper JP1AJS3-Manager JP1AJS3-Manager-to-Manager 'JP1/AJS3 Manager to JP1/AJS3 Manager' TCP @(20241,20244,20245,23160)

Name                       DisplayName                          DisplayGroup    Enabled Profile         Direction Actio
                                                                                                                  n
----                       -----------                          ------------    ------- -------         --------- -----
JP1AJS3-Manager-to-Manager JP1/AJS3 Manager to JP1/AJS3 Manager JP1AJS3-Manager False   Domain, Private Inbound   Allow


[agent]: PS C:\> fwrhelper JP1AJS3-Manager JP1AJS3-SDK-to-Manager 'JP1/AJS3 SDK to JP1/AJS3 Manager' TCP @(22250)

Name                   DisplayName                      DisplayGroup    Enabled Profile         Direction Action
----                   -----------                      ------------    ------- -------         --------- ------
JP1AJS3-SDK-to-Manager JP1/AJS3 SDK to JP1/AJS3 Manager JP1AJS3-Manager False   Domain, Private Inbound   Allow


[agent]: PS C:\> fwrhelper JP1AJS3-Agent JP1AJS3-Agent-to-Agent-TCP 'JP1/AJS3 Agent to JP1/AJS3 Agent (TCP)' TCP @(22251)

Name                       DisplayName                            DisplayGroup  Enabled Profile         Direction Actio
                                                                                                                  n
----                       -----------                            ------------  ------- -------         --------- -----
JP1AJS3-Agent-to-Agent-TCP JP1/AJS3 Agent to JP1/AJS3 Agent (TCP) JP1AJS3-Agent False   Domain, Private Inbound   Allow


[agent]: PS C:\> fwrhelper JP1AJS3-Agent JP1AJS3-Agent-to-Agent-UDP 'JP1/AJS3 Agent to JP1/AJS3 Agent (UDP)' UDP @(22251)

Name                       DisplayName                            DisplayGroup  Enabled Profile         Direction Actio
                                                                                                                  n
----                       -----------                            ------------  ------- -------         --------- -----
JP1AJS3-Agent-to-Agent-UDP JP1/AJS3 Agent to JP1/AJS3 Agent (UDP) JP1AJS3-Agent False   Domain, Private Inbound   Allow


[agent]: PS C:\> fwrhelper JP1AJS3-Manager JP1AJS3-Web-Console-to-Manager 'JP1/AJS3 Web Console to JP1/AJS3 Manager' TCP @(22250)

Name                           DisplayName                              DisplayGroup    Enabled Profile         Directi
                                                                                                                on
----                           -----------                              ------------    ------- -------         -------
JP1AJS3-Web-Console-to-Manager JP1/AJS3 Web Console to JP1/AJS3 Manager JP1AJS3-Manager False   Domain, Private Inbound


[agent]: PS C:\> fwrhelper JP1AJS3-Web-Console Web-Browser-to-JP1AJS3-Web-Console 'Web Browser to JP1/AJS3 Web Console' TCP @(22252,22253)

Name                               DisplayName                         DisplayGroup        Enabled Profile         Dire
                                                                                                                   ctio
                                                                                                                   n
----                               -----------                         ------------        ------- -------         ----
Web-Browser-to-JP1AJS3-Web-Console Web Browser to JP1/AJS3 Web Console JP1AJS3-Web-Console False   Domain, Private I...


[agent]: PS C:\>

定義されたルールの確認

定義されたルールを確認してみよう。
マネージャホストおよびエージェントホストで以下の通り実行する。

[agent]: PS C:\> Get-NetFirewallRule -Group JP1* | ft

Name                               DisplayName                              DisplayGroup        Enabled Profile
----                               -----------                              ------------        ------- -------
JP1Base-to-JP1Base                 JP1/Base to JP1/Base                     JP1Base             False   Domain, Private
JP1AJS3-to-JP1Base                 JP1/AJS3 to JP1/Base                     JP1Base             False   Domain, Private
JP1AJS3-Agent-to-Manager           JP1/AJS3 Agent to JP1/AJS3 Manaer        JP1AJS3-Manager     False   Domain, Private
JP1AJS3-Manager-to-Agent           JP1/AJS3 Manager to JP1/AJS3 Aent        JP1AJS3-Agent       False   Domain, Private
JP1AJS3-Manager-to-Manager         JP1/AJS3 Manager to JP1/AJS3 Manager     JP1AJS3-Manager     False   Domain, Private
JP1AJS3-SDK-to-Manager             JP1/AJS3 SDK to JP1/AJS3 Manager         JP1AJS3-Manager     False   Domain, Private
JP1AJS3-Agent-to-Agent-TCP         JP1/AJS3 Agent to JP1/AJS3 Agent (TCP)   JP1AJS3-Agent       False   Domain, Private
JP1AJS3-Agent-to-Agent-UDP         JP1/AJS3 Agent to JP1/AJS3 Agent (UDP)   JP1AJS3-Agent       False   Domain, Private
JP1AJS3-Web-Console-to-Manager     JP1/AJS3 Web Console to JP1/AJS3 Manager JP1AJS3-Manager     False   Domain, Private
Web-Browser-to-JP1AJS3-Web-Console Web Browser to JP1/AJS3 Web Console      JP1AJS3-Web-Console False   Domain, Private


[agent]: PS C:\>

すべてのルールが無効化されていることに注意。

必要なルールの有効化

マネージャホストおよびエージェントホストそれぞれで、その役割に必要となるルールを有効化する。

必要なルールの有効化 @ エージェントホストt

ファイアウォールグループ JP1Base および JP1AJS3-Agent を有効化する。

[agent]: PS C:\> Enable-NetFirewallRule -Group JP1Base,JP1AJS3-Agent
[agent]: PS C:\> Get-NetFirewallRule -Group JP1* | ft

Name                               DisplayName                              DisplayGroup        Enabled Profile
----                               -----------                              ------------        ------- -------
JP1Base-to-JP1Base                 JP1/Base to JP1/Base                     JP1Base             True    Domain, Private
JP1AJS3-to-JP1Base                 JP1/AJS3 to JP1/Base                     JP1Base             True    Domain, Private
JP1AJS3-Agent-to-Manager           JP1/AJS3 Agent to JP1/AJS3 Manaer        JP1AJS3-Manager     False   Domain, Private
JP1AJS3-Manager-to-Agent           JP1/AJS3 Manager to JP1/AJS3 Aent        JP1AJS3-Agent       True    Domain, Private
JP1AJS3-Manager-to-Manager         JP1/AJS3 Manager to JP1/AJS3 Manager     JP1AJS3-Manager     False   Domain, Private
JP1AJS3-SDK-to-Manager             JP1/AJS3 SDK to JP1/AJS3 Manager         JP1AJS3-Manager     False   Domain, Private
JP1AJS3-Agent-to-Agent-TCP         JP1/AJS3 Agent to JP1/AJS3 Agent (TCP)   JP1AJS3-Agent       True    Domain, Private
JP1AJS3-Agent-to-Agent-UDP         JP1/AJS3 Agent to JP1/AJS3 Agent (UDP)   JP1AJS3-Agent       True    Domain, Private
JP1AJS3-Web-Console-to-Manager     JP1/AJS3 Web Console to JP1/AJS3 Manager JP1AJS3-Manager     False   Domain, Private
Web-Browser-to-JP1AJS3-Web-Console Web Browser to JP1/AJS3 Web Console      JP1AJS3-Web-Console False   Domain, Private


[agent]: PS C:\>

必要なルールの有効化 @ マネージャホストt

ファイアウォールグループ JP1Base、JP1AJS3-Manager および JP1AJS3-Agentを有効化する。
Manager は、Agent の機能も併せ持つため、Agent 用のルールも有効化する必要がある。

[manager]: PS C:\> Enable-NetFirewallRule -Group JP1Base,JP1AJS3-Manager,JP1AJS3-Agent
[manager]: PS C:\> Get-NetFirewallRule -Group JP1* | ft

Name                               DisplayName                              DisplayGroup        Enabled Profile
----                               -----------                              ------------        ------- -------
JP1Base-to-JP1Base                 JP1/Base to JP1/Base                     JP1Base             True    Domain, Private
JP1AJS3-to-JP1Base                 JP1/AJS3 to JP1/Base                     JP1Base             True    Domain, Private
JP1AJS3-Agent-to-Manager           JP1/AJS3 Agent to JP1/AJS3 Manaer        JP1AJS3-Manager     True    Domain, Private
JP1AJS3-Manager-to-Agent           JP1/AJS3 Manager to JP1/AJS3 Aent        JP1AJS3-Agent       True    Domain, Private
JP1AJS3-Manager-to-Manager         JP1/AJS3 Manager to JP1/AJS3 Manager     JP1AJS3-Manager     True    Domain, Private
JP1AJS3-SDK-to-Manager             JP1/AJS3 SDK to JP1/AJS3 Manager         JP1AJS3-Manager     True    Domain, Private
JP1AJS3-Agent-to-Agent-TCP         JP1/AJS3 Agent to JP1/AJS3 Agent (TCP)   JP1AJS3-Agent       True    Domain, Private
JP1AJS3-Agent-to-Agent-UDP         JP1/AJS3 Agent to JP1/AJS3 Agent (UDP)   JP1AJS3-Agent       True    Domain, Private
JP1AJS3-Web-Console-to-Manager     JP1/AJS3 Web Console to JP1/AJS3 Manager JP1AJS3-Manager     True    Domain, Private
Web-Browser-to-JP1AJS3-Web-Console Web Browser to JP1/AJS3 Web Console      JP1AJS3-Web-Console False   Domain, Private


[manager]: PS C:\>

2017/02/21

PowerShellからCMD.exeやpowershell.exeのフォントを追加する

Cmd.exeやpowershell.exeなどで、Windowsのコンソール(ターミナル)を使う場合、既定では日本語が表示できるTrueTypeフォントは、MSゴシックしか選べない。
今回は、PowerShellを使ってWindowsのコンソールにフォントを追加し、選択できるようにする方法を紹介する。

フォントの準備

Windowのコンソールに追加するフォントを準備する。
これらは、いわゆる等幅フォントでなければならない。
RictyMyrica等、好みのフォントをインストールしておく。

現状設定の確認

続いて、現状の設定を確認する。
PowerShellを管理者モードで起動し、以下の通り実行する
PS C:\> $ttf = 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFont'
PS C:\> Get-Item $ttf


    Hive: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console


Name                           Property
----                           --------
TrueTypeFont                   949 : *굴림체
                               0   : Lucida Console
                               950 : *細明體
                               932 : *MS ゴシック
                               936 : *新宋体
                               00  : Consolas


PS C:\>
「MS ゴシック」とある行の「932」は、いわゆるMicrosoftコードページ932 (CP932)のこと。
既定では、CP932に対して、MSゴシック一つのみが登録されており、唯一選択可能になっていることが解る。

CP932に対して、フォントを追加する場合、この部分を932.1, 932.2, 932.3,…の様に「コードページ.番号」の様な形で追加する必要がある。

なお、選択されたフォントは、フォント名の直前に「*」がついている。
上の例では、CP932に対しては、MSゴシックが選択されていることが解る(と言っても唯一の選択肢だが)。

フォントの追加

今回は、
  • Ricty Discord
  • Ricty
  • MyricaM M
  • Myrica M
を追加する。
フォント名の部分は、適宜読み替える。

以下の通り実行する。
PS C:\> New-ItemProperty $ttf -Name 932.1 -PropertyType string -Value 'Ricty Discord'


932.1        : Ricty Discord
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFon
               t
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console
PSChildName  : TrueTypeFont
PSDrive      : HKLM
PSProvider   : Microsoft.PowerShell.Core\Registry



PS C:\> New-ItemProperty $ttf -Name 932.2 -PropertyType string -Value 'Ricty'


932.2        : Ricty
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFon
               t
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console
PSChildName  : TrueTypeFont
PSDrive      : HKLM
PSProvider   : Microsoft.PowerShell.Core\Registry



PS C:\> New-ItemProperty $ttf -Name 932.3 -PropertyType string -Value 'MyricaM M'


932.3        : MyricaM M
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFon
               t
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console
PSChildName  : TrueTypeFont
PSDrive      : HKLM
PSProvider   : Microsoft.PowerShell.Core\Registry



PS C:\> New-ItemProperty $ttf -Name 932.4 -PropertyType string -Value 'Myrica M'


932.4        : Myrica M
PSPath       : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console\TrueTypeFon
               t
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console
PSChildName  : TrueTypeFont
PSDrive      : HKLM
PSProvider   : Microsoft.PowerShell.Core\Registry



PS C:\>

結果の確認

結果を確認する。
PS C:\> Get-Item $ttf


    Hive: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Console


Name                           Property
----                           --------
TrueTypeFont                   949   : *굴림체
                               0     : Lucida Console
                               950   : *細明體
                               932   : *MS ゴシック
                               936   : *新宋体
                               00    : Consolas
                               932.1 : Ricty Discord
                               932.2 : Ricty
                               932.3 : MyricaM M
                               932.4 : Myrica M


PS C:\>
932.[1-4]にそれぞれフォントが追加されたのが判る。

この状態で、cmd.exeやpowershell.exeを起動し、プロパティ画面のフォントタブから、複数のフォントが選べるようになっていることを確認できる。

2014/06/22

NSConfigSheet

About

NSConfigSheet is a Microsoft Windows PowerShell moudle to convert a Juniper ScreenOS configuration file into a configuration sheet in format of Microsoft Word document.
You can get NSConfigSheet here:

Download

https://github.com/jolly-jive/NSConfigSheet

Install

Copy NSConfigSheet directory into any direcotory in your $env:PSModulePath.
You can also use this module without install by executing as follows:
Import-Module <<path to the NSConfigSheet directorygt;>

Licensing

NSConfigSheet is released under the General Public License version 3.
For more licensing information, see http://www.gnu.org/licenses/gpl-faq.html and http://www.gnu.org/licenses/exceptions.html.
For any copyright year range specified as YYYY-ZZZZ in this package note that the range specifies every single year in that closed interval.

Trademarks

All names of products and services are trademarks or registered trademarks of their respective companies.

2014/05/27

PowerCLI: 無償利用のESXを5.1から5.5 update 1に更新・その0・概要

ESXi 5.5 update 1が公開された。『VMware ESXi 5.5, Patch ESXi550-Update01: ESXi 5.5 Complete Update 1 (2065832)
今回は、無償ライセンスで動いているESXi 5.1を5.5 update 1に更新する方法を紹介する。
有償ライセンスで使えるコマンドレットが無償ライセンスでは使えない場合があるので、代わりにESXCLIオブジェクトを使って作業する。

その0・概要
その1・ダウンロード
その2・ESXCLIオブジェクト
その3・ゲスト機の停止
その4・メンテナンスモードへの移行
その5・更新
その6・再起動
その7・メンテナンスモードの解除

2014/05/26

PowerCLI: 無償利用のESXiにNFSデータストアを操作

PowerCLIからNFSデータストアを追加する方法を紹介する。
有償ライセンスでは、New-Datastoreコマンドレットを使うが、無償ライセンスではエラーになってしまう。これをvSphere CLI (ESXCLI)を使って回避する。

2014/05/20

PowerCLI: 無償利用のESXiでWrite操作を実行する

ESXiは、無償・無料で利用できるライセンスがあるが、PowerCLIでこのライセンスを導入したESXiに接続すると、システムの動作を変更する操作(write operation、write操作)を実行することができない。例えば、仮想ホストをメンテナンスモードに移行しようとすると、エラーになる。

実際に実行して試してみる。まず、仮想ホストesxi01に接続する。
PowerCLI vis:¥> Connect-VIServer -Server esxi01 -User 管理者ユーザ名 -Password '管理者パスワード'

Name                           Port  User
----                           ----  ----
esxi01                         443   管理者ユーザ名


PowerCLI vis:¥>

現在の状態をGet-VMHostコマンドレットを使って確認する。
PowerCLI vis:¥> Get-VMHost

Name                 ConnectionState PowerState NumCpu CpuUsageMhz CpuTotalMhz   MemoryUsageGB   MemoryTotalGB Version
----                 --------------- ---------- ------ ----------- -----------   -------------   ------------- -------
esxi01               Connected       PoweredOn       2          78        4266           1.293          11.999   5.5.0


PowerCLI vis:¥>
「ConnectionState」が「Connected」即ち、接続中であることが判る。

状態の変更には、Set-VMHostコマンドレットを使う。
PowerCLI vis:¥> Set-VMHost -State Maintenance
Set-VMHost : 2014/05/20 17:41:52    Set-VMHost        Current license or ESXi version prohibits execution of the requested operation.
発生場所 行:1 文字:1
+ Set-VMHost -State Maintenance
+ ‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾‾
    + CategoryInfo          : NotSpecified: (:) [Set-VMHost], RestrictedVersion
    + FullyQualifiedErrorId : Client20_ComputeResourceServiceImpl_VmHostEnterMaintenaceMode_ViError,VMware.VimAutomation.ViCore.
   Cmdlets.Commands.SetVMHost

PowerCLI vis:¥>
ライセンスの問題で、要求した操作を実行できない。

PowerCLI: 接続時の証明書に関する警告を抑制

ESXiインストール直後の状態では、PowerCLI上でConnect-VIServerコマンドレットなどを使って当該ESXiに接続すると、X.509証明書に関する警告が表示される。
PowerCLI vis:¥> Connect-VIServer -Server esxi01 -User 管理者ユーザ名 -Password '管理者パスワード'
警告: There were one or more problems with the server certificate for the server esxi01:443:

* The X509 chain could not be built up to the root certificate.

* The certificate's CN name does not match the passed value.

Certificate: [Subject]
  OID.1.2.840.113549.1.9.2="1333622464,564d7761726520496e632e", CN=localhost.localdomain, E=ssl-certificates@vmware.com,
OU=VMware ESX Server Default Certificate, O="VMware, Inc", L=Palo Alto, S=California, C=US

[Issuer]
  O=VMware Installer

[Serial Number]
  4A6C787339575678

[Not Before]
  2012/04/05 19:41:05

[Not After]
  2023/10/05 19:41:05

[Thumbprint]
  CAFD0D77AB938E6B5A70D01262BA4C7FC79121FA



The server certificate is not valid.

警告: THE DEFAULT BEHAVIOR UPON INVALID SERVER CERTIFICATE WILL CHANGE IN A FUTURE RELEASE. To ensure scripts are not affected by
 the change, use Set-PowerCLIConfiguration to set a value for the InvalidCertificateAction option.


Name                           Port  User
----                           ----  ----
esxi01                         443   管理者ユーザ名


PowerCLI vis:¥> 
実用上、問題は無いが、この警告を抑制する方法を紹介する。

2014/05/19

PowerCLI: VMware ESXiにライセンスをインストールする。

VMware vSphere PowerCLIは、PowerShellを使ってvShpereやvCloudを管理するコマンドレット群(cmdlets)。ESXi/ESXやvCenter Serverに接続して、対話的な管理作業が可能で、スクリプトによる管理作業の自動化することもできる。

今回は、これを使って、ライセンス導入作業を実施する。

2013/04/01

PowerShellでスマートにダウンロードする(BITS)・その3・バックグラウンド

バックグラウンドで実行するには、コマンドレットStart-BitsTransferに「-Asynchronous」オプションを与えて実行する。
PS C:\Download> Start-BitsTransfer http://ftp.nara.wide.ad.jp/pub/Linux/centos/6/isos/x86_64/CentOS-6.3-x86_64-LiveCD.iso CentOS-6.3-x86_64-LiveCD.iso -Asynchronous

JobId                      DisplayName                TransferType               JobState                   OwnerAccount
-----                      -----------                ------------               --------                   ------------
90341cf3-6ba2-4a68-b1a8... BITS Transfer              Download                   Connecting                 ホスト名\ユーザ名..


PS C:\Download>
登録されたBITSジョブの詳細が表示された後、プロンプトが表示され、制御が戻る。現在の状況は「Connecting」、つまり接続中であることが判る。

バックグラウンドの場合、進行状況がフォアグラウンドには表示されない。また、ダウンロードが完了するまで、ファイルは作成されない。
PS C:\Download> dir
PS C:\Download>
進行状況を確認するには、コマンドレットGet-BitsTransferを使う。
PS C:\Download> Get-BitsTransfer

JobId                      DisplayName                TransferType               JobState                   OwnerAccount
-----                      -----------                ------------               --------                   ------------
90341cf3-6ba2-4a68-b1a8... BITS Transfer              Download                   Transferring               ホスト名\ユーザ名..


PS C:\Download>
現在「Transferring」中、すなわち転送中であることが解る。

ダウンロードが完了した状態になると、次のように表示される。
PS C:\Download> Get-BitsTransfer

JobId                      DisplayName                TransferType               JobState                   OwnerAccount
-----                      -----------                ------------               --------                   ------------
90341cf3-6ba2-4a68-b1a8... BITS Transfer              Download                   Transferred                ホスト名\ユーザ名..


PS C:\Download>
この時点ではまだ、ファイルは存在していない。
PS C:\Download> dir
PS C:\Download>
コマンドレットComplete-BitsTransferでBITSジョブを完了させる。
PS C:\Download> Complete-BitsTransfer (Get-BitsTransfer)
PS C:\Download> Get-BitsTransfer
PS C:\Download>
BITSジョブを完了させると、BITSジョブは削除される。

BITSジョブを完了させた時点で、ファイルが作成される。
PS C:\Download> dir


    ディレクトリ: C:\Download


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2012/07/08      2:26  725614592 CentOS-6.3-x86_64-LiveCD.iso


PS C:\Download>


その1・BITSとは
その2・フォアグラウンド
その3・バックグラウンド

PowerShellでスマートにダウンロードする(BITS)・その2・フォアグラウンド

フォアグラウンドでダウンロードする場合、コマンドレットStart-BitsTransferを以下の通り使用する。
PS C:\ISO> Start-BitsTransfer http://ftp.nara.wide.ad.jp/pub/Linux/centos/6/isos/x86_64/CentOS-6.3-x86_64-LiveCD.iso CentOS-6.3-x86_64-LiveCD.iso
フォアグラウンドの場合、進行状況が表示される。終了すると、プロンプトが表示される。確認してみよう。
PS C:\ISO> Start-BitsTransfer http://ftp.nara.wide.ad.jp/pub/Linux/centos/6/isos/x86_64/CentOS-6.3-x86_64-LiveCD.iso CentOS-6.3-x86_64-LiveCD.iso
PS C:\ISO> dir


    ディレクトリ: C:\ISO


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2012/07/08      2:26  725614592 CentOS-6.3-x86_64-LiveCD.iso


PS C:\ISO>


その1・BITSとは
その2・フォアグラウンド
その3・バックグラウンド

PowerShellでスマートにダウンロードする(BITS)・その1・BITSとは

WindowsでHTTPやFTPでダウンロードする必要がある場合、どういう方法で行うだろうか? もちろん、ダウンロード専用のソフトウェアを別途導入可能であれば、そうするのが簡単だ。
そうでない場合、例えば、自由にソフトウェアを導入できない環境であれば、通常IEを利用するだろう。
今回は、別途ソフトウェアも導入せず、IEも使わない方法を紹介したい。それは、PowerShellからBackground Intelligent Transfer Service (BIS)を利用する方法だ。
Background Intelligent Transfer Service (BITS, バックグラウンド インテリジェント転送サービス)は、アイドル中のネットワーク回線の帯域幅を使用し、非同期にマシン間のファイル転送を行うMicrosoft Windows オペレーティングシステムの構成の一部である。Windows Update、Windows Server Update Services、System Management Serverやその他のアプリケーションやWindows サービスで利用されている。
BITSを使えば、ユーザサービスに与える影響を最小化してダウンロードを実行可能だ。また、ダウンロードを一時休止・再開することもできる。
PowerShellでは、BITSを操作するコマンドとして、以下のものが準備されている。
PS C:\> Get-Command -Noun BITS*

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Cmdlet          Add-BitsFile                                       BitsTransfer
Cmdlet          Complete-BitsTransfer                              BitsTransfer
Cmdlet          Get-BitsTransfer                                   BitsTransfer
Cmdlet          Remove-BitsTransfer                                BitsTransfer
Cmdlet          Resume-BitsTransfer                                BitsTransfer
Cmdlet          Set-BitsTransfer                                   BitsTransfer
Cmdlet          Start-BitsTransfer                                 BitsTransfer
Cmdlet          Suspend-BitsTransfer                               BitsTransfer


PS C:\>

その1・BITSとは
その2・フォアグラウンド
その3・バックグラウンド

2012/12/19

PowerShellでGoogle Apps Email Migration APIを呼び出す

PowerShell Advent Calendar 2012参加企画。

この記事では、PowerShellでGoogle Apps Email Migration APIを呼び出すC#サンプルスクリプトをPowerShellに移植したものを紹介する。

PowerShellの利点はいくつもあるが、特筆すべきは以下の点だろう。
  • 対話的コマンドラインインターフェース(CLI)を備えている
  • プログラミング言語として現代的な文法を備えている
  • .NET Frameworkを扱うことができる
最初と二番目は、PowerShellは、CMD.exeでできたことを網羅しつつ、現代的な文法を備えたスクリプト言語、と言うことだ。Windows標準環境では、CMD.exeを使うことができたが、文法が貧弱でプログラミングが困難だった。同じくWindows標準環境では、VBScriptやJScriptなどの現代的なスクリプト言語が使えたが、対話的CLIが無かった。
三番目だが、Windows標準環境では、.NET Frameworkの重要度が上がっているが、CMD.exeではこれを直接扱う方法が無かった。PowerShellでは可能になった。

そこで、この記事では、PowerShellから.NET Frameworkへアクセスするスクリプトを紹介する。ただ、PowerShellから標準的な.NET Frameworkのライブラリにアクセスする方法は、他にもいい記事があるので、改めて紹介する意味は薄い。ここでは少し趣向を変え、PowerShellからGoogle Apps Email Migration APIを使う例を紹介する。Google Apps Email Migration APIのクライアントライブラリは、Java版・Python版の他に.NET版も提供されている。このサンプルスクリプトmigrationsample.csをPowerShellに移植した。コードmigrationsample.ps1(ダウンロード)は以下の通り。
<#
.SYNOPSIS
Sample script to demonstrate the use of the Google Apps Domain Migration API client library.

.DESCRIPTION
Sample script to demonstrate the use of the Google Apps Domain Migration API client library.
The original C# version is from https://developers.google.com/google-apps/email-migration/.

.INPUTS
Nothing.

.OUTPUTS
Nothing.
#>

[CmdletBinding()param(
    # The hosted domain (e.g. example.com) in which the migration will occur.
    [String]
    [parameter(Mandatory=$true)]
    $domain,

    # The username of the administrator or user migrating mail.
    [String]
    [parameter(Mandatory=$true)]
    $adminUsername,

    # The password of the administrator or user migrating mail.
    [String]
    [parameter(Mandatory=$true)]
    $adminPassword,

    # The username to which emails should be migrated.
    # End users can only transfer mail to their own mailboxes.
    # If unspecified, will default to login_email.
    [String]
    [parameter(Mandatory=$true)]
    $destinationUser = ''
)

#####
$REDIST_PATH = "$Env:ProgramFiles\Google\Google Data API SDK\Redist"
Add-Type -Path "$REDIST_PATH\Google.GData.Apps.dll"
Add-Type -Path "$REDIST_PATH\Google.GData.Client.dll"
Add-Type -Path "$REDIST_PATH\Google.GData.Extensions.dll"

$LabelFriend = New-Object Google.GData.Extensions.Apps.LabelElement("Friends")
$LabelEventInvitations = New-Object Google.GData.Extensions.Apps.LabelElement("Event Invitations")

$PropertyElementINBOX = [Google.GData.Extensions.Apps.MailItemPropertyElement]::INBOX
$PropertyElementSTARRED = [Google.GData.Extensions.Apps.MailItemPropertyElement]::STARRED
$PropertyElementUNREAD = [Google.GData.Extensions.Apps.MailItemPropertyElement]::UNREAD


[String]$rfcTxt = @"
Received: by 10.143.160.15 with HTTP; Mon, 16 Jul 2007 10:12:26 -0700 (PDT)
Message-ID: <_message_id_ mail.gmail.com="mail.gmail.com">
Date: Mon, 16 Jul 2007 10:12:26 -0700
From: "Mr. Serious" <serious adomain.com="adomain.com">
To: "Mr. Admin" <testadmin apps-provisioning-test.com="apps-provisioning-test.com">
Subject: Random Subject
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Delivered-To: testadmin@apps-provisioning-test.com

This is a message delivered via DMAPI
"@

$random = New-Object Random


if($destinationUser -eq '') {
    $destinationUser = $adminUsername
}


$mailItemService = New-Object Google.GData.Apps.Migration.MailItemService($domain, "Sample Migration Application")
$mailItemService.setUserCredentials("$adminUsername@$domain", $adminPassword)


<#
.DESCRIPTION
Generates a random RFC822 message based on the template in rfcTxt.
We have to randomly modify the subject and message ID to prevent duplicate
supression by the Gmail server.

.INPUTS
Nothing.

.OUTPUTS
The randomly-modified RFC822 message.
#>
Function GenerateRandomRfcText
{
    ($rfcTxt -replace "Random Subject", "Random Subject $($random.Next())") `
        -replace "_message_id_", "$($random.Next())"
}


<#
.DESCRIPTION
Helper method to set up a new MailItemEntry.

.INPUTS
Nothing.

.OUTPUTS
The newly created MailItemEntry.
#>
Function SetupMailItemEntry
{
    param(
        # The batch ID for this entry.
        [String]$batchId
    )

    $entry = New-Object Google.GData.Apps.Migration.MailItemEntry

    [void]$entry.Labels.Add($LabelFriend)
    [void]$entry.Labels.Add($LabelEventInvitations)

    [void]$entry.MailItemProperties.Add($PropertyElementINBOX)
    [void]$entry.MailItemProperties.Add($PropertyElementSTARRED)
    [void]$entry.MailItemProperties.Add($PropertyElementUNREAD)

    $entry.Rfc822Msg = New-Object Google.GData.Extensions.Apps.Rfc822MsgElement(GenerateRandomRfcText)

    $entry.BatchData = New-Object Google.GData.Client.GDataBatchEntryData
    $entry.BatchData.Id = $batchId

    $entry
}


<#
.DESCRIPTION
Demonstrates inserting several mail items in a batch.

.INPUTS
Nothing.

.OUTPUTS
A MailItemFeed with the results of the insertions.
#>
Function BatchInsertMailItems
{
    param(
        # The number of entries to insert.
        [Int]$numToInsert
    )

    [Google.GData.Apps.Migration.MailItemEntry[]]$entries = @()

    # Set up the mail item entries to insert.
    foreach($index in 0..($numToInsert-1)) {
        $entries += SetupMailItemEntry([String]$index)
    }

    # Execute the batch request and print the results.
    [Google.GData.Apps.Migration.MailItemFeed]$batchResult = $mailItemService.Batch($domain, $destinationUser, $entries)
    [Google.GData.Client.AtomEntry]$entry = $Null
    foreach($entry in $batchResult.Entries) {
        [Google.GData.Client.GDataBatchEntryData]$batchData = $entry.BatchData

        Write-Host "Mail message $($batchData.Id): $($batchData.Status.Code) $($batchData.Status.Reason)"
    }

    $batchResult
}

try {
    # Insert several emails in a batch.
    [Google.GData.Apps.Migration.MailItemFeed]$batchResults = BatchInsertMailItems(10)
} catch [Google.GData.Client.GDataRequestException] {
    Write-Host ("Operation failed ({0}): {1}" -f $Error[0].Message, $Error[0].ResponseString)
}

使い方は次の通り。
migrationsample.ps1 domain userEmail password [destinationEmail]
ここで、domainは、Google Appsのドメイン名、userEmailpasswordは、対象となるユーザの資格情報。もしdestinationEmailを与えると、対象となるユーザを指定したことになり、その場合、userEmailpasswordは、Google Appsのドメイン管理者の資格情報を与える必要がある。

以下はその実行例。
PS C:\Users\user01> .\migrationsample.ps1 example.co.jp appsmaster 'password' appsuser
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
PS C:\Users\user01>
この例では、10通すべてのメールデータの処理結果が状態コード201で、Google Apps上に移行されたことが判る。

なお、このコードを実行するためには、事前に次の作業を実行しておく必要がある。
  1. Google Data APIクライアントライブラリのダウンロードおよびインストール
  2. PowerShell実行ポリシの変更

実際のメールデータ移行作業での注意点については、こちらを参照して欲しい。

2012/12/04

Outlookのメッセージ作成で意図しないフォントが使われる

Outlookには、妙な「仕様」がある。メッセージを作成するときに、意図しないフォントが使われることがあるのだ(詳細は後述)。
これは、『KB414804: [OL2002] 半角英数字の入力時に フォントが Arial で表示される』でも触れられているのだが、MSによれば「仕様」であって、バグではないそうだ。これを回避するには、レジストリを操作する必要があるが、今回は、これをPowerShellで実行する方法を紹介する。

[Windows]+[R]でpowershellを起動し、以下の通り実行する。
PS C:\> New-ItemProperty 'HKCU:\Software\Microsoft\Office\11.0\Outlook\Preferences' -Name 'DontUseDualFont' -value 1 -propertyType DWORD


DontUseDualFont : 1
PSPath          : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Outlook\Preferences
PSParentPath    : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsoft\Office\11.0\Outlook
PSChildName     : Preferences
PSDrive         : HKCU
PSProvider      : Microsoft.PowerShell.Core\Registry



PS C:\>
なお、上はOutlook2003の例。引数中の「11.0」は、Outlookのバージョンによって適宜換える必要がある。

以下、詳細。

Outlook 2003の場合、「ツール(T)」→「オプション(O)...」で、「オプション」ダイアログを表示される。


メッセージ形式に「テキスト形式」が選択されていることが確認できる。

さらに、「メール形式」タブ→「フォント(F)...」ボタンを押下すると、「フォント」ダイアログが表示される。


メッセージのフォントに「MS 明朝, 9 pt」が選択されていることが確認できる。

この状態でメッセージを作成した場合、常識的に考えれば、全角文字・半角文字双方にMS明朝が使われることが期待されるが、実際にはそうならない。メッセージを新規作成し、「テストtest」と入力し、その行をコピーして、次の行にペーストしてみよう。


 一行目と二行目の「test」のフォントが違うのが判る。


この二行をMS-Word等にコピー&ペーストしてみると判るが、一行目はArialで、二行目はMS明朝だ。

ここで、上の対策を実施し、Outlookを再起動して、同じようにメッセージを作成してみる。


期待通り、一行目と二行目の「test」のフォントが同じになった。


この二行をMS-Word等にコピー&ペーストすると、一行目・二行目共にMS明朝になっているのが判る。

この現象は、「テキスト形式」の場合だけでなく、「リッチテキスト形式」の場合にも発生する。

2012/12/03

The Sample Code of Google Apps Email Migration API in PowerShell

Google Apps Email Migration APIの.NET版のサンプルコードmigrationsample.csは、拡張子から判る通り、C#で記述してある。これをコンパイルして実行する方法は、『Google Apps Email Migration APIのC#サンプルプログラムをコンパイルし実行』で紹介した。

しかし、メールデータの移行と言った、一度しか行わないような作業に関して、C#の様なコンパイラ言語を使うのは牛刀割鶏、大げさすぎる。そこでこの記事では、Windowsの新スクリプト言語であるPowerShellを使う方法を紹介する。

コードmigrationsample.ps1(ダウンロード)は以下の通り。
<#
.SYNOPSIS
Sample script to demonstrate the use of the Google Apps Domain Migration API client library.

.DESCRIPTION
Sample script to demonstrate the use of the Google Apps Domain Migration API client library.
The original C# version is from https://developers.google.com/google-apps/email-migration/.

.INPUTS
Nothing.

.OUTPUTS
Nothing.
#>

[CmdletBinding()param(
    # The hosted domain (e.g. example.com) in which the migration will occur.
    [String]
    [parameter(Mandatory=$true)]
    $domain,

    # The username of the administrator or user migrating mail.
    [String]
    [parameter(Mandatory=$true)]
    $adminUsername,

    # The password of the administrator or user migrating mail.
    [String]
    [parameter(Mandatory=$true)]
    $adminPassword,

    # The username to which emails should be migrated.
    # End users can only transfer mail to their own mailboxes.
    # If unspecified, will default to login_email.
    [String]
    [parameter(Mandatory=$true)]
    $destinationUser = ''
)

#####
$REDIST_PATH = "$Env:ProgramFiles\Google\Google Data API SDK\Redist"
Add-Type -Path "$REDIST_PATH\Google.GData.Apps.dll"
Add-Type -Path "$REDIST_PATH\Google.GData.Client.dll"
Add-Type -Path "$REDIST_PATH\Google.GData.Extensions.dll"

$LabelFriend = New-Object Google.GData.Extensions.Apps.LabelElement("Friends")
$LabelEventInvitations = New-Object Google.GData.Extensions.Apps.LabelElement("Event Invitations")

$PropertyElementINBOX = [Google.GData.Extensions.Apps.MailItemPropertyElement]::INBOX
$PropertyElementSTARRED = [Google.GData.Extensions.Apps.MailItemPropertyElement]::STARRED
$PropertyElementUNREAD = [Google.GData.Extensions.Apps.MailItemPropertyElement]::UNREAD


[String]$rfcTxt = @"
Received: by 10.143.160.15 with HTTP; Mon, 16 Jul 2007 10:12:26 -0700 (PDT)
Message-ID: <_message_id_ mail.gmail.com="mail.gmail.com">
Date: Mon, 16 Jul 2007 10:12:26 -0700
From: "Mr. Serious" 
To: "Mr. Admin" 
Subject: Random Subject
MIME-Version: 1.0
Content-Type: text/plain; charset=ISO-8859-1; format=flowed
Content-Transfer-Encoding: 7bit
Content-Disposition: inline
Delivered-To: testadmin@apps-provisioning-test.com

This is a message delivered via DMAPI
"@

$random = New-Object Random


if($destinationUser -eq '') {
    $destinationUser = $adminUsername
}


$mailItemService = New-Object Google.GData.Apps.Migration.MailItemService($domain, "Sample Migration Application")
$mailItemService.setUserCredentials("$adminUsername@$domain", $adminPassword)


<#
.DESCRIPTION
Generates a random RFC822 message based on the template in rfcTxt.
We have to randomly modify the subject and message ID to prevent duplicate
supression by the Gmail server.

.INPUTS
Nothing.

.OUTPUTS
The randomly-modified RFC822 message.
#>
Function GenerateRandomRfcText
{
    ($rfcTxt -replace "Random Subject", "Random Subject $($random.Next())") `
        -replace "_message_id_", "$($random.Next())"
}


<#
.DESCRIPTION
Helper method to set up a new MailItemEntry.

.INPUTS
Nothing.

.OUTPUTS
The newly created MailItemEntry.
#>
Function SetupMailItemEntry
{
    param(
        # The batch ID for this entry.
        [String]$batchId
    )

    $entry = New-Object Google.GData.Apps.Migration.MailItemEntry

    [void]$entry.Labels.Add($LabelFriend)
    [void]$entry.Labels.Add($LabelEventInvitations)

    [void]$entry.MailItemProperties.Add($PropertyElementINBOX)
    [void]$entry.MailItemProperties.Add($PropertyElementSTARRED)
    [void]$entry.MailItemProperties.Add($PropertyElementUNREAD)

    $entry.Rfc822Msg = New-Object Google.GData.Extensions.Apps.Rfc822MsgElement(GenerateRandomRfcText)

    $entry.BatchData = New-Object Google.GData.Client.GDataBatchEntryData
    $entry.BatchData.Id = $batchId

    $entry
}


<#
.DESCRIPTION
Demonstrates inserting several mail items in a batch.

.INPUTS
Nothing.

.OUTPUTS
A MailItemFeed with the results of the insertions.
#>
Function BatchInsertMailItems
{
    param(
        # The number of entries to insert.
        [Int]$numToInsert
    )

    [Google.GData.Apps.Migration.MailItemEntry[]]$entries = @()

    # Set up the mail item entries to insert.
    foreach($index in 0..($numToInsert-1)) {
        $entries += SetupMailItemEntry([String]$index)
    }

    # Execute the batch request and print the results.
    [Google.GData.Apps.Migration.MailItemFeed]$batchResult = $mailItemService.Batch($domain, $destinationUser, $entries)
    [Google.GData.Client.AtomEntry]$entry = $Null
    foreach($entry in $batchResult.Entries) {
        [Google.GData.Client.GDataBatchEntryData]$batchData = $entry.BatchData

        Write-Host "Mail message $($batchData.Id): $($batchData.Status.Code) $($batchData.Status.Reason)"
    }

    $batchResult
}

try {
    # Insert several emails in a batch.
    [Google.GData.Apps.Migration.MailItemFeed]$batchResults = BatchInsertMailItems(10)
} catch [Google.GData.Client.GDataRequestException] {
    Write-Host ("Operation failed ({0}): {1}" -f $Error[0].Message, $Error[0].ResponseString)
}
このコードを実行するには、Google Data APIをインストールしておく必要がある。『Google Data API Installer MSIのダウンロード』および『Google Data API Installer MSIのインストール』の通りにインストールする。
また、『PowerShell実行ポリシの変更』の通り、ローカルスクリプトを実行できるようPowerShellの実行ポリシを変更しておく必要もある。

以下の通り実行する。
PS C:\Users\user01> .\migrationsample.ps1 example.co.jp appsmaster 'password' appsuser
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
Mail message : 201 Created
PS C:\Users\user01>
この例では、10通すべてのメールデータの処理結果が状態コード201で、Google Apps上に移行されたことが判る。

なお、実際のメールデータを移行した場合、以下のような結果を得る。
状態コード201 / Created
正常終了。Google Apps上にメールデータが作成された。ただし、このメッセージを受けてから、Gmailのウェブインターフェース上から参照できるようになるまでには、若干(数分間~数十分間)時間がかかることがある。
状態コード400 / Permanent failure: BadAttachment
添付ファイル形式の異常。Gmailでは、実行形式の添付ファイルが禁止されているが、その様なメールを移行しようとした場合。
状態コード400 / Permanent failure: Insert failed, badly formed message.
メールのサイズが大きすぎる。最大一通当り10MB。
状態コード400 / Bad Request
RFC5322形式(所謂RFC822形式)として正しくないデータ。ドキュメントによると、From:To:、およびDate:のヘッダフィールドが必須。未検証。
状態コード503 / The server is currently busy and could not complete your request. Please try again in 30 seconds.
クラウド側が高負荷状態のため、処理に失敗した。ドキュメントによると、この状態コードを得た場合、xponential backoff方式で再試行せよ、とある。例えば、1回この状態なら次の再試行は30秒後、続けて2回この状態なら次の再試行は60秒後、…と言う様に、続けてn回この状態なら次の再試行は30×2^(n-1)秒後、と言う様に処理する。
実行時エラー
以下の様な実行時エラーが発生する場合がある。バッチ呼び出しの最大サイズ制限に抵触している場合などに発生する。一回のバッチ呼び出しで、メールサイズの合計は、25MB以下に抑えなければならない。
"3" 個の引数を指定して "Batch" を呼び出し中に例外が発生しました: "転送接続にデータを書き込めません: 既存の接続はリモート ホストに強制的に切断されました。。"
発生場所 C:\path\to\script.ps1:line number 文字:charactor number
+                 [Google.GData.Apps.Migration.MailItemFeed]$result = $script:mailItemService.Batch <<<< ($domain, $user, $list)
    + CategoryInfo          : NotSpecified: (:) []、MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException
"3" 個の引数を指定して "Batch" を呼び出し中に例外が発生しました: "Execution of request failed: https://apps-apis.google.com/a/feeds/migration/2.0/example.com/username/mail/batch"
発生場所 C:\path\to\script.ps1:line number 文字:charactor number
+                 [Google.GData.Apps.Migration.MailItemFeed]$result = $script:mailItemService.Batch <<<< ($domain, $user, $list)
    + CategoryInfo          : NotSpecified: (:) []、MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

コーディング上注意して欲しいのは、メールデータはUTF-8でなければならない点。日本語のメールデータは通常、ISO-2022-JPで符号化されているため、そのままでは不正なデータとされ、処理されない。これを回避するためには、メールデータ全体をBASE64で符号化する必要がある。

2012/11/29

Google Apps Email Migration APIのC#サンプルプログラムをコンパイルし実行・その7・サンプルコードのコンパイル

[Windows]+[R]を押下する。


PowerShellを通常モードで起動する。

応答ファイルを準備する

C#コンパイラの応答ファイル(Response File)を準備する。

応答ファイルGoogleDataAPI.rspを以下の通り作成する。
PS C:\Users\user01\Downloads> $REDIST="$Env:Programfiles\Google\Google Data API SDK\Redist"
PS C:\Users\user01\Downloads> $(echo "/lib:`"$REDIST`""; dir $REDIST\*.dll -exclude 'zlib.*' | foreach {"/r:$($_.Name)"}) > GoogleDataAPI.rsp
PS C:\Users\user01\Downloads>

内容を確認する。
PS C:\Users\user01\Downloads> cat .\GoogleDataAPI.rsp
/lib:"C:\Program Files\Google\Google Data API SDK\Redist"
/r:Google.GData.AccessControl.DLL
/r:Google.GData.Analytics.dll
/r:Google.GData.Apps.dll
/r:Google.GData.Blogger.dll
/r:Google.GData.Calendar.dll
/r:Google.GData.Client.dll
/r:Google.GData.Contacts.dll
/r:Google.GData.ContentForShopping.dll
/r:Google.GData.Documents.dll
/r:Google.GData.Extensions.dll
/r:Google.GData.Photos.dll
/r:Google.GData.Spreadsheets.dll
/r:Google.GData.WebmasterTools.dll
/r:Google.GData.YouTube.dll
/r:Newtonsoft.Json.dll
PS C:\Users\user01\Downloads>


Aliasの設定

C#コンパイラcsc.exeは、インストールされている.Net Frameworkのバージョン毎に存在していて、PATHが通っていない。毎回フルパスで指定するのは煩雑なので、エイリアスを設定する。以下の通り作業する。ここでは、.Net Framework v3.5のcsc.exeを使う。
PS C:\Users\user01\Downloads> Set-Alias csc $Env:windir\Microsoft.NET\Framework\v3.5\csc.exe
PS C:\Users\user01\Downloads> 

以下の通り確認する。
PS C:\Users\user01\Downloads> csc
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.5420
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.

fatal error CS2008: 入力が指定されていません。
PS C:\Users\user01\Downloads>

コンパイル

その1・サンプルコードのダウンロード』でダウンロードしたmigrationsample.csをコンパイルする。コンパイルする際、前に作成した応答ファイルGoogleDataAPI.rspを指定する。
PS C:\Users\user01\Downloads> csc '@GoogleDataAPI.rsp' migrationsample.cs
Microsoft (R) Visual C# 2008 Compiler version 3.5.30729.5420
for Microsoft (R) .NET Framework version 3.5
Copyright (C) Microsoft Corporation. All rights reserved.

warning CS1685: 定義済みの型 'System.Runtime.CompilerServices.ExtensionAttribute' は、グローバル
        エイリアスの複数のアセンブリ内で定義されています。'c:\Program Files\Reference
        Assemblies\Microsoft\Framework\v3.5\System.Core.dll' からの定義を使用してください。
PS C:\Users\user01\Downloads> 

警告が表示されるが、コンパイルは正常に終了していて、migrationsample.exeが作成されている。
PS C:\Users\user01\Downloads> dir


    ディレクトリ: C:\Users\user01\Downloads


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
-a---        2012/10/17     23:09       2433 Add-AssemblyToGlobalAssemblyCache.ps1
-a---        2012/10/17     23:18       1046 GoogleDataAPI.rsp
-a---        2012/10/17     22:38   29167616 Google_Data_API_Setup_2.1.0.0.msi
-a---        2012/10/17     22:29       8008 migrationsample.cs
-a---        2012/10/17     23:33       9728 migrationsample.exe


PS C:\Users\user01\Downloads>

引数を与えずに実行すると、使い方が表示される。
PS C:\Users\user01\Downloads> .\migrationsample.exe
Usage:
  migration_sample    [destination_email]

domain:
  The hosted domain (e.g. example.com) in which the migration will occur.

login_user:
  The username of the administrator or user migrating mail.

login_password:
  The password of the administrator or user migrating mail.

destination_user:
  The username to which emails should be migrated. End users can only transfer mail to their own mailboxes.  If unspecified, will default to login_email.
PS C:\Users\user01\Downloads>


その0・概要
その1・サンプルコードのダウンロード
その2・Google Data API Installer MSIのダウンロード
その3・Global Assembly Cache Toolのダウンロードと改造
その4・Google Data API Installer MSIのインストール
その5・PowerShell実行ポリシの変更
その6・Google Data APIアセンブリのGACへのインストール
その7・サンプルコードのコンパイル

Google Apps Email Migration APIのC#サンプルプログラムをコンパイルし実行・その6・Google Data APIアセンブリのGACへのインストール

PowerShellを管理者モードで起動する。


「スタート」ボタンから、「すべてのプログラム」→「アクセサリ」→「Windows PowerShell」の順で開き、「Windows PowerShell」を右クリックし、「管理者として実行(A)...」を選択する。


UACダイアログが表示される。確認し、「はい(Y)」ボタンを押下する。

Googe Data APIが正常にインストールされていれば、以下の通りDLLが確認できる。
PS C:\Users\user01\Downloads> $REDIST="$Env:Programfiles\Google\Google Data API SDK\Redist"
PS C:\Users\user01\Downloads> dir $REDIST


    ディレクトリ: C:\Program Files\Google\Google Data API SDK\Redist


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        2012/10/17     22:59            Debug
-a---        2012/05/27     16:49      24576 Google.GData.AccessControl.DLL
-a---        2012/05/27     16:49      24064 Google.GData.Analytics.dll
-a---        2012/05/27     16:49      73728 Google.GData.Apps.dll
-a---        2012/05/27     16:49       8192 Google.GData.Blogger.dll
-a---        2012/05/27     16:49      36864 Google.GData.Calendar.dll
-a---        2012/05/27     16:49     212992 Google.GData.Client.dll
-a---        2012/05/27     16:49      29184 Google.GData.Contacts.dll
-a---        2012/05/27     16:49      39424 Google.GData.ContentForShopping.dll
-a---        2012/05/27     16:49      53248 Google.GData.Documents.dll
-a---        2012/05/27     16:49      90112 Google.GData.Extensions.dll
-a---        2012/05/27     16:49      45056 Google.GData.Photos.dll
-a---        2012/05/27     16:49      40960 Google.GData.Spreadsheets.dll
-a---        2012/05/27     16:49      24064 Google.GData.WebmasterTools.dll
-a---        2012/05/27     16:49      73728 Google.GData.YouTube.dll
-a---        2012/05/27     16:49     375296 Newtonsoft.Json.dll
-a---        2012/05/27     16:49      59904 zlib.x86.dll


PS C:\Users\user01\Downloads>
しかし、インストール直後は、これらがglobal assembly cache(以下、GAC)にはインストールされていない。以下の通り確認する。

PS C:\Users\user01\Downloads> dir "$Env:windir\assembly\GAC_MSIL" -filter "Google*"
PS C:\Users\user01\Downloads>

Google Data APIのアセンブリをGACにインストールする。以下の通り実行する。

PS C:\Users\user01\Downloads> $REDIST_PATH = "$Env:ProgramFiles\Google\Google Data API SDK\Redist"
PS C:\Users\user01\Downloads> dir $REDIST\*.dll -exclude 'zlib.*' | .\Add-AssemblyToGlobalAssemblyCache.ps1
PS C:\Users\user01\Downloads>

GACにインストールされたことを以下の通り確認する。

PS C:\Users\user01\Downloads> dir "$Env:windir\assembly\GAC_MSIL" -filter "Google*"


    ディレクトリ: C:\Windows\assembly\GAC_MSIL


Mode                LastWriteTime     Length Name
----                -------------     ------ ----
d----        2012/10/17     23:11            Google.GData.AccessControl
d----        2012/10/17     23:11            Google.GData.Analytics
d----        2012/10/17     23:11            Google.GData.Apps
d----        2012/10/17     23:11            Google.GData.Blogger
d----        2012/10/17     23:11            Google.GData.Calendar
d----        2012/10/17     23:11            Google.GData.Client
d----        2012/10/17     23:11            Google.GData.Contacts
d----        2012/10/17     23:11            Google.GData.Documents
d----        2012/10/17     23:11            Google.GData.Extensions
d----        2012/10/17     23:11            Google.GData.Photos
d----        2012/10/17     23:11            Google.GData.Spreadsheets
d----        2012/10/17     23:11            Google.GData.YouTube


PS C:\Users\user01\Downloads>


その0・概要
その1・サンプルコードのダウンロード
その2・Google Data API Installer MSIのダウンロード
その3・Global Assembly Cache Toolのダウンロードと改造
その4・Google Data API Installer MSIのインストール
その5・PowerShell実行ポリシの変更
その6・Google Data APIアセンブリのGACへのインストール
その7・サンプルコードのコンパイル

Google Apps Email Migration APIのC#サンプルプログラムをコンパイルし実行・その5・PowerShell実行ポリシの変更

OSインストール直後の状態では、ローカルのPowerShellスクリプトを実行できない。これを変更する。
PowerShellを管理者モードで起動する。


「スタート」ボタンから、「すべてのプログラム」→「アクセサリ」→「Windows PowerShell」の順で開き、「Windows PowerShell」を右クリックし、「管理者として実行(A)...」を選択する。


UACダイアログが表示される。確認し、「はい(Y)」ボタンを押下する。

PS C:\Users\user01\Downloads> Set-ExecutionPolicy RemoteSigned -Force
PS C:\Users\user01\Downloads>


その0・概要
その1・サンプルコードのダウンロード
その2・Google Data API Installer MSIのダウンロード
その3・Global Assembly Cache Toolのダウンロードと改造
その4・Google Data API Installer MSIのインストール
その5・PowerShell実行ポリシの変更
その6・Google Data APIアセンブリのGACへのインストール
その7・サンプルコードのコンパイル

Google Apps Email Migration APIのC#サンプルプログラムをコンパイルし実行・その4・Google Data API Installer MSIのインストール

Google Data APIをインストールする。


』で保存したGoogle_Data_API_Setup_2.1.0.0.msiをダブルクリックする。


「Google Data API SDK Setup Wizard」が起動される。「Next>」ボタンを押下する。


Everyone」ラジオボタンを選択し、「Next>」ボタンを押下する。


Next>」ボタンを押下する。


進行状況が表示される。


UACダイアログが表示される。確認の上、「はい(Y)」ボタンを押下する。


進行状況が表示される。


インストールが正常終了したことを確認し、「Close>」ボタンを押下する。


その0・概要
その1・サンプルコードのダウンロード
その2・Google Data API Installer MSIのダウンロード
その3・Global Assembly Cache Toolのダウンロードと改造
その4・Google Data API Installer MSIのインストール
その5・PowerShell実行ポリシの変更
その6・Google Data APIアセンブリのGACへのインストール
その7・サンプルコードのコンパイル

Google Apps Email Migration APIのC#サンプルプログラムをコンパイルし実行・その3・Global Assembly Cache Toolのダウンロードと改造

ダウンロード

Global Assembly Cache Tool in PowerShell: Add-AssemblyToGlobalAssemblyCache.ps1

ブラウザで『The Identity Management Explorer: Use Powershell to put your assemblies in the GAC』を開く。


画面中央「script」リンクをクリックする。


「ダウンロード」ボタンを押下する。


「直接ダウンロード」を選択する。


「保存(S)」ボタンを押下し、ファイルを適切な場所に

ブロックの解除

ダウンロードしたファイルに対して、以下を実行する。


右クリックから「プロパティ(R)」を選択する。


「ブロックの解除(K)」ボタンを押下する。

スクリプトの修正

ダウンロードしたAdd-AssemblyToGlobalAssemblyCache.ps1を改造する。このスクリプトは、アセンブリをglobal assembly cache(以下、GAC)にインストールするが、オリジナル版のスクリプトは、アセンブリがデジタル署名されていることを必須条件としている。

一方、『その2・Google Data API Installer MSIのダウンロード』でダウンロードしたGoogle_Data_API_Setup_2.1.0.0.msiでインストールされるDLLは、デジタル署名されていない。このため、このままではこのスクリプトではこれらのDLLをGACに登録できない。

以下の通り編集する。

メモ帳でAdd-AssemblyToGlobalAssemblyCache.ps1を開く。
PS C:\Users\user01\Downloads> notepad .\Add-AssemblyToGlobalAssemblyCache.ps1

赤字の部分を追加する。
$LoadedAssembly = [System.Reflection.Assembly]::LoadFile($Assembly)

#        if ($LoadedAssembly.GetName().GetPublicKey().Length -eq 0)
#        {
#            throw "The assembly '$Assembly' must be strongly signed."
#        }

        Write-Verbose "Installing: $Assembly"
        $PublishObject.GacInstall($Assembly)


その0・概要
その1・サンプルコードのダウンロード
その2・Google Data API Installer MSIのダウンロード
その3・Global Assembly Cache Toolのダウンロードと改造
その4・Google Data API Installer MSIのインストール
その5・PowerShell実行ポリシの変更
その6・Google Data APIアセンブリのGACへのインストール
その7・サンプルコードのコンパイル

Google Apps Email Migration APIのC#サンプルプログラムをコンパイルし実行・その2・Google Data API Installer MSIのダウンロード

ダウンロード

ブラウザで『Protocol Basics - Google Data APIs ― Google Developers』を開く。


Audience」リンクをクリックする。


client libraries」リンクをクリックする。


画面を下に移動する。


「.Net」行の「Library Download」列「Download」リンクをクリックする。


Google_Data_API_Setup_2.1.0.0.msi」リンクをクリックする。


Google_Data_API_Setup_2.1.0.0.msi」リンクをクリックする。


「保存(S)」ボタンを押下し、適切な場所にファイルを保存する。

ブロックの解除


ダウンロードしたファイル対して、以下を実行する。



右クリックから「プロパティ(R)」を選択する。


「ブロックの解除(K)」ボタンを押下する。


その0・概要
その1・サンプルコードのダウンロード
その2・Google Data API Installer MSIのダウンロード
その3・Global Assembly Cache Toolのダウンロードと改造
その4・Google Data API Installer MSIのインストール
その5・PowerShell実行ポリシの変更
その6・Google Data APIアセンブリのGACへのインストール
その7・サンプルコードのコンパイル