Windows

複数のDCがある環境でGPOが適用されないので調べてみたらDC間でGPOが同期されていなかった。
イベントログには イベントID 13508 ソース NtFrs が出てる。

グループポリシーエディタでドメイン名を右クリックすると各DC内に保存されている設定内容が表示されるので、各DCの中の設定を比較してみるとさっき変更した部分が同期されてない。
複製がうまくいってないといということね。

FRS(File Replication Service)を再起動してもダメだったので以下を参照
http://support.microsoft.com/kb/290762

要はSYSVOL または DFS 共有内のファイルが一貫していない場合に手動で再複製する方法です。

手順は以下の通り

権限のある複製(正常な方)としてFRSを停止してから
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NtFrs\Parameters\Backup/Restore\Process at Startup の BurFlagsを「D4」(DWORD)にセット

権限のない復元(↑のやつが複製される側)としてFRSを停止してから
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\NtFrs\Parameters\Backup/Restore\Process at Startup の BurFlagsを「D2」(DWORD)にセット

双方のサーバーでFRSを起動すっとD4をセットしたサーバーの内容がD2へ複製されます。

正常に同期が行われるとイベントログのファイルレプリケーションサービスに 13516 13553 13554 等が出るはず。


そもそもなんでこのエラーが起きたのか分からなかったのですが、DCをVMWareへP2Vしたタイミングな気がします。理由は不明(笑)

リモートデスクトップでプリンタがリダイレクト(マッピング?)されない場合の対処方法

MSにも情報がありましたが、現在のバージョンのRDPクライアント(6.1以上)ではレジストリの変更は必要ないみたいです。うちでは繋がりました。

 

まずサーバーにドライバを入れる。

中略

 

で、クライアントはプリンタのマップを行えば繋がります。

 

これでも繋がらない!という場合以下をチェック。

ここは外します。

 

ここでハマったんですが、↑でOKを押すと「現在のセッションには適用されません」というメッセージが表示されます。
なんで再起動不要かと思いましたが、あれこれ試した結果再起動したらサクっといきました。お試しあれ。

EVE-FA, ActiveDirectory, IDマネージャ, Cybozuのアカウント更新用スクリプト

各グループウェア等のアカウント更新用スクリプト。
batファイルより4つCSVを引数に渡して、EVE-FAのユーザー情報を元にパスワードを設定。
アカウント更新用のCSVをエクスポートします。

引数の順番は固定で、全てのCSVを渡すことが必須条件です。


[ evefa-ad-idm-cybozu.bat ]
-----
echo on
evefa-ad-idm-cybozu.pl eve-fa.csv ad.txt idm.csv cybozu.csv
[EOF]
-----


[ evefa-ad-idm-cybozu.pl ]
-----
#!/usr/local/bin/perl

sub createPass(){
    $chars = "012345678abcdefghijklmnorsuvwxyz";
    $len = length( $chars );
    $password = "";
    for( $i = 0; $i < 8; $i++ ){
        $password .= substr( $chars, int( rand( $len )), 1 );
        @password = $password;
    }
    return ($password);
}
sub getTime(){
    my $time = time();
    my ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime($time);
    my $result = sprintf("%04d%02d%02d", $year + 1900, $mon + 1, $mday);
    return $result;
}

sub evefa_ad(){
    my $INFILE = $_[0];
    open(IN, "$INFILE");
    my $outfile = " $_[0]".getTime().".txt";
    open(OUT, ">> $outfile");
    while ($line = <IN>) {
        chomp($line);
        if($line ne ''){
            my @arrays = split( /,/, $line );
            @arrays[4] = createPass();
            $ret = "";
            $len =  $#arrays + 1;
            for($i=0; $i<$len; $i++){
                if($i == $len){
                    $ret = $ret.@arrays[$i];
                }else{
                    $ret = $ret.@arrays[$i].',';
                }
            }
            print(OUT "$ret\n");
        }
    }
    close(IN);
    close(OUT);
}

sub ad_conv(){
    my $EVEFILE = " $_[0]".getTime().".txt";
    my $INFILEA = $_[1];
    
    my $outfile = " $_[1]".getTime().".txt";
    open(OUT, ">> $outfile");

    open(ADIN, "$INFILEA");
    
    
    while ($ad_line = <ADIN>) {
        chomp($ad_line);
        if($ad_line ne ''){
            @ad_array = split (/\s+/, $ad_line);
        }
        if(@ad_array[2] eq "no"){
            $userName = @ad_array[1];
            if($userName ne ''){
                $userName = (split( /@/, $userName))[0];
                
                open(EVEIN, "$EVEFILE");
                while($eve_line = <EVEIN>){
                    chomp($eve_line);
                    if($eve_line ne ''){
                        my @arrays = split( /,/, $eve_line );
                        my $eve_ac = @arrays[3];
                        my $pass = @arrays[4];
                        if($userName eq $eve_ac){
                            print (OUT "$userName,$pass\n");
                        }
                    }
                }
                close(EVEIN);
            }
        }
    }
    close(ADIN);
    close(OUT);
}

sub idm(){
    my $EVEFILE = " $_[0]".getTime().".txt";
    my $INFILE = $_[1];
    my $outfile = " $_[1]".getTime().".txt";
    open(OUT, ">> $outfile");
    open(INFILE, "$INFILE");
    
    while ($idm_line = <INFILE>) {
        chomp($idm_line);
        if($idm_line ne ''){
            @idm_array = split (/,/, $idm_line);
        }
        if(@idm_array[3] == 1){
            open(EVEIN, "$EVEFILE");
            while($eve_line = <EVEIN>){
                chomp($eve_line);
                if($eve_line ne ''){
                    my @arrays = split( /,/, $eve_line );
                    my $eve_ac = @arrays[3];
                    my $pass = @arrays[4];
                    my $idm_ac = @idm_array[0];
                    my $idm_mail = @idm_array[6];
                    
                    if($idm_mail =~ /^[^@]+@[^.]+\..+/){
                        @idm_array[7] = $pass;
                    }else{
                        @idm_array[7] = "";
                    }
                    if($idm_ac eq $eve_ac){
                        
                        
                        $ret = "";
                        $len =  $#idm_array + 1;
                        for($i=0; $i<$len; $i++){
                            if($i == $len){
                                $ret = $ret.@idm_array[$i];
                            }else{
                                $ret = $ret.@idm_array[$i].',';
                            }
                        }
                        print(OUT "$ret\n");
                        $ret = "";
                    }
                }
            }
            close(EVEIN);
        }
    }
    close(INFILE);
    close(OUT);
}

sub cybozu(){
    my $IDMFILE = " $_[0]".getTime().".txt";
    my $CYBOZUFILE = $_[1];
    
    my $outfile = " $_[1]".getTime().".txt";
    open(OUT, ">> $outfile");
    open(IDMFILE, "$IDMFILE");

    while($idm_line = <IDMFILE>){
        chomp($idm_line);
        if($idm_line ne ''){
            my @idm_arrays = split( /,/, $idm_line );
            my $idm_ac = @idm_arrays[6];
            my $idm_pass = @idm_arrays[7];
            
            open(CYBOZUFILE, "$CYBOZUFILE");
            while ($cyb_line = <CYBOZUFILE>) {
                chomp($cyb_line);
                if($cyb_line ne ''){
                    @cyb_array = split (/,/, $cyb_line);
                }
                $len =  $#cyb_array + 1;
                for($i=0; $i<$len; $i++){ @cyb_array[$i] =~ s/\"//g; }
                
                
                my $cyb_login = @cyb_array[2];
                if($idm_ac eq $cyb_login && $cyb_login =~ /^[^@]+@[^.]+\..+/){
                    @cyb_array[3] = $idm_pass;
                    $ret = "";
                    for($i=0; $i<$len; $i++){
                        if($i == $len){
                            $ret = $ret.@cyb_array[$i];
                        }else{
                            $ret = $ret.@cyb_array[$i].',';
                        }
                    }
                    print(OUT "$ret\n");
                }
            }
            close(CYBOZUFILE);
        }
    }
    close(IDMFILE);
    close(OUT);
}

&evefa_ad(@ARGV[0]);
&ad_conv(@ARGV[0], @ARGV[1]);
&idm(@ARGV[0], @ARGV[2]);
&cybozu(@ARGV[2], @ARGV[3]);

[EOF]
-----

上記Perlスクリプトにて生成されたADアカウント情報のCSVを読み込んで一括設定するBatファイル。
[ ad_updateRead.bat ]
-----
echo off
FOR /F "eol=# tokens=1,2 delims=," %%a in (hoge.txt) do ad_update.bat %%a %%b
[EOF]
-----

net userコマンドにてADのアカウントを更新。

[ad_update.bat]
-----
echo off
net user "%1" "%2" /DOMAIN
[EOF]
-----

以下のようなエラーが出た場合の対処方法

イベントの種類:    エラー
イベント ソース:    DCOM
イベント カテゴリ:    なし
イベント ID:    10016
日付:        2000/01/01
時刻:        9:00:00
ユーザー:        NT AUTHORITY\NETWORK SERVICE
コンピュータ:    SRV01
説明:
machine-default 権限の設定では、CLSID
{BA126AD1-2166-11D1-B1D0-00805FC1270E}
 をもつ COM サーバー アプリケーションに対する Local Activation アクセス許可をユーザーNT AUTHORITY\NETWORK SERVICE SID (S-1-5-20) に与えることはできません。このセキュリティのアクセス許可は、コンポーネント サービス管理ツールを使って変更できます。

BA126AD1-2166-11D1-B1D0-00805FC1270E は Network Connection Manager Class
またこの中にあるキー 27AF75ED-20D9-11D1-B1CE-00805FC1270E は netman ということ。
レジストリを検索するとすぐ分かる。

DCOMエラーなので「管理ツール」>「コンポーネントサービス」を開き、
コンピュータ>マイコンピュータ>DCOMの構成>netman>プロパティ>セキュリティ。

起動とアクティブ可のアクセス許可>カスタマイズに「NETWORK SERVICE」を追加し「ローカルからの起動」と「ローカルからのアクティブ化」にチェックを入れてOK。

適用したら15分ほど待ってイベントログを確認し、エラーが出ていなければ解決。


Userenv 1517の場合。

--------------------------------
イベントの種類: 警告
イベント ソース: Userenv
イベント カテゴリ: なし
イベント ID: 1517
日付: 2009/10/03
時刻: 2:17:47
ユーザー: NT AUTHORITY\SYSTEM
コンピュータ: LONDON

説明:
ログオフ時にアプリケーションまたはサービスがレジストリをまだ使用している間に、Windows はユーザー LONDON\hoehoe のレジストリを保存しました。ユーザーのレジストリによって使用されたメモリは解放されていません。レジストリは使用されなくなったときにアンロードされます。

ユーザー アカウントとしてサービスを実行していることが原因と考えられます。 LocalService または NetworkService アカウントでサービスを構成してみてください。

詳細な情報は、http://go.microsoft.com/fwlink/events.asp の [ヘルプとサポート センター] を参照してください。
--------------------------------

UPHClean-Setup.msiを
http://www.microsoft.com/downloads/details.aspx?FamilyID=1b286e6d-8912-4e18-b570-42470e2f3582&DisplayLang=ja
からダウンロード・インストール。

一応Windowsの終了が早くなったりする...らしいです。

以下のようなエラーが出る場合

イベントの種類:    エラー
イベント ソース:    Userenv
イベント カテゴリ:    なし
イベント ID:    1508
日付:        2000/01/01
時刻:        12:12:12
ユーザー:        NT AUTHORITY\SYSTEM
コンピュータ:    PC
説明:
レジストリを読み込めませんでした。メモリ不足またはセキュリティ不足が原因であると考えられます。

 DETAIL - システム リソースが不足しているため、要求されたサービスを完了できません。  - D:\Documents\user-a\ntuser.dat

イベントの種類:    エラー
イベント ソース:    Userenv
イベント カテゴリ:    なし
イベント ID:    1500
日付:        2000/01/01
時刻:        12:12:12
ユーザー:        DOMAIN\user-a
コンピュータ:    PC
説明:
プロファイルを読み込めないためログオンできません。ネットワークに接続していること、またネットワークが正しく機能していることを確認してください。問題が解決しない場合は、ネットワーク管理者に問い合わせてください。

 詳細 - システム リソースが不足しているため、要求されたサービスを完了できません。

本当にリソースが不足している場合は再起動で一時的な対応は可能。
慢性的なリソース不足の場合はメモリなどの増設が必須となる。

またターミナルサーバーの場合はセッションの数を以下のように調整することで対応が可能となることもある。
リソースに余裕があるのに不足と警告される場合は自己責任で試してみるといいかも。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Session Manager\Memory に
DWORD 値 PoolUsageMaximum 値は10進数で96。

同じ場所にPagedPoolSize のレジストリ エントリが存在しない場合作成する。
DWORD 値 ffffffff 16進。

要再起動。


別のパターンでプロファイルが腐っているケースがあるので、その場合は上記で言うuser-aのフォルダにアクセス権を再適用。

フォルダを右クリ>共有とセキュリティ>セキュリティ>詳細設定>子オブジェクト全てのアクセス許可エントリ(長い・・・)にチェックを入れて置換。

おかしなファイルがあれば削除したほうがいい(と思う)。

.NET Framework3.5 SP1 以降。Windows XP 以降に対応です。

WCFでの実装になりますが、WS-Security(HTTPS)を利用する場合、残念ながらこの機能は利用出来ません。
SOAP(HTTP)でなら、GZipでの圧縮が有効になります。


えー、出来ましたので、別 途掲載させて頂きます。m(_"_)m

開発環境は VisualStudio 2008 C# です。


まずはサービス側。

pjl-comp-filter でGzip圧縮します。pjl-comp-filter.jar と web.xmlだけでOKです。

[ web.xml ]
----------------------
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
    "http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
    <display-name>Service</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/com/chocbanana/ws/cxf.xml</param-value>
    </context-param>

    <!-- Filter config with GZIP -->
    <filter>
        <filter-name>CompressingFilter</filter-name>
        <filter-class>
            com.planetj.servlet.filter.compression.CompressingFilter
        </filter-class>
        <init-param>
            <param-name>debug</param-name>
            <param-value>false</param-value>
        </init-param>
        <init-param>
            <param-name>statsEnabled</param-name>
            <param-value>true</param-value>
        </init-param>
    </filter>

    <filter-mapping>
        <filter-name>CompressingFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

   
    <servlet>
        <servlet-name>context</servlet-name>
        <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>MessageBrokerServlet</servlet-name>
        <servlet-class>flex.messaging.MessageBrokerServlet</servlet-class>
        <init-param>
            <param-name>services.configuration.file</param-name>
            <param-value>/WEB-INF/flex/services-config.xml</param-value>
        </init-param>
        <load-on-startup>3</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>ScheduleStarter</servlet-name>
        <servlet-class>com.chocbanana.schedule.ScheduleStarter</servlet-class>
        <load-on-startup>4</load-on-startup>
    </servlet>

    <servlet>
          <servlet-name>FileUpServlet</servlet-name>
          <servlet-class>com.chocbanana.csv.Upload</servlet-class>
    </servlet>

    <servlet-mapping>
        <servlet-name>MessageBrokerServlet</servlet-name>
        <url-pattern>/messagebroker/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

    <servlet-mapping>
        <servlet-name>FileUpServlet</servlet-name>
        <url-pattern>/fileup/*</url-pattern>
    </servlet-mapping>

    <mime-mapping>
        <extension>wsdl</extension>
        <mime-type>text/xml</mime-type>
    </mime-mapping>
</web-app>
[ EOF ]
----------------------

[ com.chocbanana.ws.Service.java ]
----------------------
package com.chocbanana.ws;

import javax.jws.WebService;
import javax.jws.WebMethod;

@WebService
public class Service implements IService{

    public Service(){
    }
       
    @WebMethod
    public String hello(){
        return "Hello";
    }
}
[ EOF ]
----------------------


んで、WCF側。


前準備としてGZipライブラリが必要になるので、それを用意します。

http://www.microsoft.com/Downloads/details.aspx?familyid=ED9C315C-31AC-4CCB-B62B-721AF1E2BFA8&displaylang=en
より WCF_WF_Samples.exe をダウンロードします。

それを解凍した中に、WCFWFCardSpace\WCF\Extensibility\MessageEncoder\Compression\CS があるので、それをVS2008で少し改変してビルドしておきます。
このソリューションのビルドが成功すると GZipEncoder.dll が作成されますので、GZip圧縮にはこのDLLを利用します。

以下改変部分。

-------------
1) GZipMessageEncoderFactory.cs
        //This is the actual GZip encoder
        class GZipMessageEncoder : MessageEncoder
        {
            //static string GZipContentType = "application/x-gzip";
            static string GZipContentType = "text/xml"; // 置換

2) GZIPMessageEncodingBindingElement.cs
        public GZipMessageEncodingBindingElement(MessageEncodingBindingElement messageEncoderBindingElement)
        {
            this.innerBindingElement = messageEncoderBindingElement;
            this.innerBindingElement.MessageVersion = MessageVersion.Soap11; // 追加
        }
-------------


あとは以 前作ったこのコードとapp.configに修正を加えます。
使用するプロジェクトにGZipEncoder.dll をインポートして、Microsoft.ServiceModel.Samplesの参照設定を行って下さい。

以下サンプル用ソースコード。

[ app.config ]
-----------------------
<?xml version="1.0"?>
<configuration>
  <configSections>
    <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
      <section name="WCF_TEST.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false"/>
    </sectionGroup>
  </configSections>
  <system.serviceModel>
    <behaviors>
      <endpointBehaviors>
        <behavior name="ClientCredentialsBehavior">
          <clientCredentials>
            <serviceCertificate>
              <authentication certificateValidationMode="None" revocationMode="NoCheck"/>
            </serviceCertificate>
          </clientCredentials>
        </behavior>
      </endpointBehaviors>
    </behaviors>

    <extensions>
      <bindingElementExtensions>
        <add name="gzipMessageEncoding" type="Microsoft.ServiceModel.Samples.GZipMessageEncodingElement, GZipEncoder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
      </bindingElementExtensions>
    </extensions>

    <bindings>
      <basicHttpBinding>
        <binding name="BasicHttpBinding_Service" closeTimeout="00:01:00"
          openTimeout="00:01:00" receiveTimeout="00:10:00" sendTimeout="00:01:00"
          allowCookies="false" bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
          maxBufferSize="65536" maxBufferPoolSize="524288" maxReceivedMessageSize="65536"
          messageEncoding="Text" textEncoding="utf-8" transferMode="Buffered"
          useDefaultWebProxy="true">
          <readerQuotas maxDepth="32" maxStringContentLength="8192" maxArrayLength="16384"
            maxBytesPerRead="4096" maxNameTableCharCount="16384" />
          <security mode="Transport">
            <transport clientCredentialType="None" proxyCredentialType="None"
              realm="" />
            <message algorithmSuite="Default" />
          </security>
        </binding>
      </basicHttpBinding>
      <customBinding>
        <binding name="ISampleServer">
          <gzipMessageEncoding innerMessageEncoding="textMessageEncoding" />
          <httpTransport manualAddressing="false" authenticationScheme="None"
            bypassProxyOnLocal="false" hostNameComparisonMode="StrongWildcard"
            proxyAuthenticationScheme="Basic" realm="" useDefaultWebProxy="false" />
        </binding>
      </customBinding>
    </bindings>
    <client>
      <endpoint address="https://127.0.0.1:8443/services/Service" behaviorConfiguration="ClientCredentialsBehavior"
        binding="basicHttpBinding" bindingConfiguration="BasicHttpBinding_Service"
        contract="ims.IService" name="BasicHttpBinding_Service" />
      <endpoint address="http://127.0.0.1:8080/services/Service" binding="customBinding"
        bindingConfiguration="ISampleServer" contract="ims.IService"
        name="SoapBinding_Service" />
      <metadata>
        <policyImporters>
          <extension type="Microsoft.ServiceModel.Samples.GZipMessageEncodingBindingElementImporter, GZipEncoder, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
        </policyImporters>
      </metadata>
    </client>
  </system.serviceModel>

  <applicationSettings>
    <WCF_TEST.Properties.Settings>
      <setting name="ProxyServer" serializeAs="String">
        <value>http://proxyserver:8080/</value>
      </setting>
      <setting name="OutputFile" serializeAs="String">
        <value>detault.xml</value>
      </setting>
      <setting name="OutputFileFlag" serializeAs="String">
        <value>FALSE</value>
      </setting>
      <setting name="Debug" serializeAs="String">
        <value>FALSE</value>
      </setting>
      <setting name="ProxyEnabled" serializeAs="String">
        <value>FALSE</value>
      </setting>
      <setting name="Domain" serializeAs="String">
        <value>DOMAIN</value>
      </setting>
      <setting name="AdminUser" serializeAs="String">
        <value>Administrator</value>
      </setting>
      <setting name="AdminPass" serializeAs="String">
        <value>password</value>
      </setting>
      <setting name="AdminDomain" serializeAs="String">
        <value>LONDON</value>
      </setting>
      <setting name="EncryptPassword" serializeAs="String">
        <value>OFF</value>
      </setting>
      <setting name="Binding" serializeAs="String">
        <value>SoapBinding_Service</value>
      </setting>
      <setting name="Address" serializeAs="String">
        <value>https://chocbanana.com/services/Service</value>
      </setting>
      <setting name="SOAP_Address" serializeAs="String">
        <value>http://chocbanana.com/services/Service</value>
      </setting>
    </WCF_TEST.Properties.Settings>
  </applicationSettings>
  <startup>
    <supportedRuntime version="v2.0.50727"/>
  </startup>
</configuration>
[ EOF ]
-----------------------


[ Program.cs ]
-----------------------
using System;
using System.Collections.Generic;
using System.Text;
using ims;
using System.ServiceModel;
using System.ServiceModel.Channels;
using Microsoft.ServiceModel.Samples;
using System.Net;

namespace WCF_TEST {
    class Program {
        static void Main(string[] args) {
            try {
                show();
            } catch (Exception e) {
                Console.WriteLine("msg: " + e.Message);
                Console.WriteLine("data: " + e.Data);
                Console.WriteLine("src: " + e.Source);
                Console.WriteLine("trace: " + e.StackTrace);
            }
        }

        private static void show() {
            string Address = Properties.Settings.Default.Address;
            string Binding = Properties.Settings.Default.Binding;
            ServiceClient service = null;
            if (Address.StartsWith("https://") && Binding == "BasicHttpBinding_Service") {

                //証明書の確認用EvnetHandlerをコール
                ConfirmCertificatePolicy.ConfirmCertificatePolicy_CallEventHandler();
                ims.ServiceClient proxy = new ims.ServiceClient("BasicHttpBinding_Service",
                    new System.ServiceModel.EndpointAddress(Properties.Settings.Default.Address));
                string proxyEnabled = Properties.Settings.Default.ProxyEnabled;

                if (proxyEnabled == "TRUE") {
                    string proxyServer = Properties.Settings.Default.ProxyServer;
                    BasicHttpBinding httpBindingElement = (BasicHttpBinding)proxy.Endpoint.Binding;
                    httpBindingElement.BypassProxyOnLocal = true;
                    httpBindingElement.UseDefaultWebProxy = false;
                    httpBindingElement.ProxyAddress = new Uri(proxyServer);
                    proxy.Endpoint.Binding = httpBindingElement;
                }

                Console.WriteLine(proxy.hello());
                proxy.Close();

            } else {
                ICollection<BindingElement> bindingElements = new List<BindingElement>();
                HttpTransportBindingElement httpBindingElement = new HttpTransportBindingElement();
                string proxyEnabled = Properties.Settings.Default.ProxyEnabled;
                if (proxyEnabled == "TRUE") {
                    string proxyServer = Properties.Settings.Default.ProxyServer;
                    httpBindingElement.BypassProxyOnLocal = true;
                    httpBindingElement.UseDefaultWebProxy = false;
                    httpBindingElement.ProxyAddress = new Uri(proxyServer);
                }

                //httpBindingElement.AuthenticationScheme = AuthenticationSchemes.Basic;

                GZipMessageEncodingBindingElement compBindingElement = new GZipMessageEncodingBindingElement();
                bindingElements.Add(compBindingElement);
                bindingElements.Add(httpBindingElement);

                CustomBinding myBinding = new CustomBinding(bindingElements);
                myBinding.Name = "SoapBinding_Service";
                myBinding.Namespace = "http://ws.chocbanana.com/";


                // Webサービスインスタンス生成 //
                Address = Properties.Settings.Default.SOAP_Address;
                service = new ims.ServiceClient(myBinding, new EndpointAddress(Address));

                HttpRequestMessageProperty httpRequestProperty = new HttpRequestMessageProperty();

                httpRequestProperty.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip");
                httpRequestProperty.Headers.Add(HttpRequestHeader.ContentEncoding, "gzip");

                using (OperationContextScope scope = new OperationContextScope(service.InnerChannel)) {
                    OperationContext.Current.OutgoingMessageProperties
                    [HttpRequestMessageProperty.Name] = httpRequestProperty;
                    Console.WriteLine(service.hello());
                }
            }
        }
    }
}
[ EOF ]
-----------------------

参考サイトURL
http://www.vistax64.com/indigo/113763-wcf-client-j2ee-server-using-gzip.html


VBScriptとJavaScriptが混在するWSHスクリプトの参考例です。

注意点は2点のみ...だと思います。
1.  拡張子をwsfにする
2. 1つのファイル内に <SCRIPT language=JScript> <SCRIPT language=VBScript> とScript宣言を行う

以下参照
[ callJS.wsf ]
----------------------
<JOB>
    <SCRIPT language=JScript>
        function hello() {
            return ("Hello");
        }
    </SCRIPT>

    <SCRIPT language=VBScript>
        MsgBox hello()
    </SCRIPT>
</JOB>
[ EOF ]
----------------------

あ、追記。

呼び出す方のScript定義を先に書いておかないとダメだそうです。
VBScriptからJavaScriptを呼び出すなら、JavaScriptを先に。
JavaScriptからVBScriptを呼び出すなら、VBScriptを先に。

以上です。
[ 以下参照 ]
--------------
Option Explicit

const HKCU = &H80000001
Dim strComputer
Dim reg
Dim strKeyPath
Dim arrSubKeys
Dim sbukey
Dim dbxFilePath
Dim objNet
Dim objFSO
Dim objFiles
Dim objFile
Dim strMessage
Dim subkey
Dim sid
Dim fileSize
Dim strFileSize

Function checkDbxFile()
    Set objFSO = WScript.CreateObject("Scripting.FileSystemObject")
    Set objNet = WScript.CreateObject("WScript.Network")
    
    strComputer = "."
    Set reg=GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
    strKeyPath = "Identities"
    
    reg.EnumKey HKCU, strKeyPath, arrSubKeys
    For Each subkey In arrSubKeys
        If subkey <> "" Then
            sid = subkey
        End If
    Next
    
    dbxFilePath = "C:\Documents and Settings\" & objNet.UserName & "\Local Settings\Application Data\Identities\" & sid & "\Microsoft\Outlook Express\"
    
    'MsgBox dbxFilePath
    
    Set objFiles = objFSO.GetFolder(dbxFilePath).Files
    
    For Each objFile In objFiles
           'ファイル名を取得
           fileSize = objFile.Size
           If fileSize >= 1024 Then
               fileSize = fileSize / 1024
               strFileSize = CStr(fileSize) & "KB"
               If fileSize >= 1024 Then
                   fileSize = fileSize / 1024
                   strFileSize = CStr(fileSize) & "MB"
                   If fileSize >= 1024 Then
                       fileSize = fileSize / 1024
                       strFileSize = CStr(fileSize) & "GB"
                       If fileSize >= 1.5 Then
                           strMessage = strMessage & objNet.ComputerName & " - " & objNet.userName & ": " & objFile.Name & _
                                "/" & strFileSize & vbCrLf
                       End If
    
                   End If
               End If
           End If
    Next
    
    '戻り値を設定してExit
    checkDbxFile = strMessage
    Exit Function
End Function

MsgBox checkDbxFile
[EOF]
--------------

作業時間30分。...コレくらいは作れるようになろうね...。

んで、こ れと組み合わせるときは・・・、mail_send()の中で判定すれば良いのかな?

Sub mail_send()
    Dim message

    ...ごにょごにょ

    message = checkDbxFile
    oMsg.TextBody = message

    ...ごにょごにょ

    If message <> "" Then
          oMsg.Send
    End If
End Sub

これで良いんじゃない?

以下のようなエラーが出た場合の対処について。
アクセス権を変更すればOKです。

イベントの種類:    エラー
イベント ソース:    DCOM
イベント カテゴリ:    なし
イベント ID:    10016
日付:        2000/01/01
時刻:        9:00:00
ユーザー:        NT AUTHORITY\NETWORK SERVICE
コンピュータ:    PC
説明:
machine-default 権限の設定では、CLSID
{XXXX6AD1-2166-XXXX-B1D0-00805FC1XXXX}
 をもつ COM サーバー アプリケーションに対する Local Activation アクセス許可をユーザーNT AUTHORITY\NETWORK SERVICE SID (S-1-5-20) に与えることはできません。このセキュリティのアクセス許可は、コンポーネント サービス管理ツールを使って変更できます。

1.レジストリエディタを開き HKEY_CLASSES_ROOT\CLSID\ 以下の該当するキーを捜す
 (上記の例だと XXXX6AD1-2166-XXXX-B1D0-00805FC1XXXX )
2.該当するキー以下のAppID(REG_SZ)値を確認する
3.管理ツール>コンポーネントサービスを開く
4.コンポーネントサービス>コンピュータ>マイコンピュータ>DCOMの構成を開く
5.2で確認した値を探す 今回のケースですと netman でした。
6.イベントログでは ユーザーNT AUTHORITY\NETWORK SERVICE にアクセス許可が無いと言っているので
 プロパティ>セキュリティ>アクセス許可より NETWORK SERVICE を追加してローカルアクセスを許可する

telnet SERVER-NAME とすると以下のメッセージが出てアクセスが拒否される。

Access Denied: Specified user is not a member of TelnetClients group.
Server administrator must add this user to the above group.

Telnet Server has closed the connection
ホストとの接続が切断されました。

前は普通に接続できたような気がするんだけどな・・・

理屈はすっ飛ばしてやり方だけ。
NTLMを無効にすることで接続できるみたいです。

telnet として
Microsoft Telnet> unset NTLM <入力
自動認証 (NTLM 認証) を使わない
Microsoft Telnet> open SERVER-NAME <入力

これで接続可能。もとに戻すときはset NTLMで。

Welcome to Microsoft Telnet Service

login: administrator
password:


 まーたドキュメント探し回ったので、memoしておきます。
 WCFでのProxy部分の設定ね。

 SOAPの場合は
 Service s = new Service();
  service.Proxy = new System.Net.WebProxy(proxyServer);
  で出来たのに、WCFの場合はちょっと違ったので。以下サンプル。


[ WCFインスタンスの生成 ]
----------------
        private ServiceClient getServiceObj() {

            //証明書の確認用EvnetHandlerをコール
            ConfirmCertificatePolicy.ConfirmCertificatePolicy_CallEventHandler();

            /* Webサービスインスタンス生成 -URLはApp.configから読み込み- */
            string URL = IntraMasterOne.Properties.Settings.Default.HTTPS_URL;
            ServiceClient service = new ims.ServiceClient("BasicHttpBinding_Service",
                                                                new System.ServiceModel.EndpointAddress(URL));

            /* ProxyServerがあるか? */
            string proxyEnabled = global::IntraMasterOne.Properties.Settings.Default.ProxyEnabled;
            if (proxyEnabled == "TRUE") {
                string proxyServer = global::IntraMasterOne.Properties.Settings.Default.ProxyServer;
                BasicHttpBinding binding = (BasicHttpBinding)service.Endpoint.Binding;
                binding.BypassProxyOnLocal = true;
                binding.UseDefaultWebProxy = false;
                binding.ProxyAddress = new Uri(proxyServer);

                service.Endpoint.Binding = binding;
            }
            return service;
        }
[ EOF ]
------------------


[ 証明書の確認用EvnetHandler  ]
------------------
        public static void ConfirmCertificatePolicy_CallEventHandler() {
            ServicePointManager.ServerCertificateValidationCallback += RemoteCertValidation;
        }

        /* オレオレ証明書の場合はエラーになるので、エラーでもTrueを返しておきます。 */
        public static bool RemoteCertValidation(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error) {
            //if (error != SslPolicyErrors.None)
            //{
            //Console.WriteLine("証明書に問題があります。理由:" + chain.ChainStatus[0].StatusInformation);
            //Console.Write("処理を続行しますか? y:続行:");
            //string input = Console.ReadLine();
            //if (input.ToLower() == "y")
            //    return true;
            //else
            //    return false;
            //}
            return true;
        }
[EOF]
------------------

 一旦BasicHttpBindingを取り出して、設定後にWCFインスタンスにプロパティを設定しなおせばおk。



Visual Studio 2008 C# Express Edition の WCF を使用して Apache CXF と連携させます。
んで、ついでにhttpsで経路の暗号化。

動作環境は.NET Framework3.5以上なので、WindowsXP以降になります。
svcutil.exeにて作成したスタブをVS2005のProjectにインポートしてコンパイルすれば、.NET Framework2.0でも動作可能です。
従って、.NET Framework2.0が動作するOSであればOKかと。
コンパイルは通ったけど、Win2kで実行したらエラーになりますた。orz

サーバー側はJavaが動けば何でも良いです。


サーバー側(Java)

WebコンテナはCaucho Resin 3.0.27 J2EE Server + Apache CXF

あらかじめSSLの証明書を作成しておきます。
場所は /usr/local/resin-3.0.27/keys/server.key に保存して下さい。

J2SE6.0 に付属している keytool.exeで作成します。

[ keys.bat ]
----------------
echo on
"C:\Program Files\Java\jdk1.6.0_13\bin\keytool.exe" -genkey -keyalg RSA -keystore keys/server.key
----------------
 
さらに、Resinの設定ファイルである resin.conf( /usr/local/resin-3.0.27/conf/resin.conf ) を書き換えます。

[ resin.conf ]
--------------------
    <!--
       - SSL port configuration:
       -
       - <http port="8443">
       -   <openssl>
       -     <certificate-file>keys/gryffindor.crt</certificate-file>
       -     <certificate-key-file>keys/gryffindor.key</certificate-key-file>
       -     <password>test123</password>
       -   </openssl>
       - </http>
      -->
       <http port="8443">
            <jsse-ssl>
                <key-store-type>jks</key-store-type>
                <key-store-file>keys/server.key</key-store-file>
                <password>password</password>
            </jsse-ssl>
       </http>
--------------------

これで httpsで経路を暗号化して通信することが出来るようになりました。
今回はWebコンテナレベルでHTTPS実装を行いましたが、アプリケーションレベルまで落としても良いと思います。

で、Java(サーバー)側のサービスメソッド。

[ com.chocbanana.ws.Service ]
------------------------------
package com.chocbanana.ws;

import javax.jws.WebService;
import javax.jws.WebMethod;

@WebService
public class Service implements IService{
    public Service(){

    }

    @WebMethod
    public String hello(){
        return "Hello";
    }
}
------------------------------


[ com/chocbanana/ws/cxf.xml ]
------------------------------
<beans xmlns="http://www.springframework.org/schema/beans"
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
      xmlns:jaxws="http://cxf.apache.org/jaxws"
      xsi:schemaLocation="http://www.springframework.org/schema/beans
                     http://www.springframework.org/schema/beans/spring-beans.xsd
                     http://cxf.apache.org/jaxws
                     http://cxf.apache.org/schemas/jaxws.xsd">

    <import resource="classpath:META-INF/cxf/cxf.xml" />
    <import resource="classpath:META-INF/cxf/cxf-extension-soap.xml"/>
    <import resource="classpath:META-INF/cxf/cxf-servlet.xml" />

    <jaxws:endpoint id="service" implementor="com.chocbanana.ws.Service" address="/Service" />
</beans>
------------------------------


[ web.xml ]
------------------------------
<?xml version="1.0"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">

<web-app>
    <display-name>Service</display-name>
    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>classpath:/com/chocbanana/ws/cxf.xml</param-value>
    </context-param>

    <servlet>
        <servlet-name>context</servlet-name>
        <servlet-class>org.springframework.web.context.ContextLoaderServlet</servlet-class>
        <load-on-startup>1</load-on-startup>
    </servlet>

    <servlet>
        <servlet-name>CXFServlet</servlet-name>
        <servlet-class>org.apache.cxf.transport.servlet.CXFServlet</servlet-class>
        <load-on-startup>2</load-on-startup>
    </servlet>

    <servlet-mapping>
        <servlet-name>CXFServlet</servlet-name>
        <url-pattern>/services/*</url-pattern>
    </servlet-mapping>

    <mime-mapping>
        <extension>wsdl</extension>
        <mime-type>text/xml</mime-type>
    </mime-mapping>
</web-app>
------------------------------




クライアント(WCFホスト)

.NET Framework3.5に付属している svcutil.exeでスタブを作成します。

[ svcutil.bat ]
------------------
echo on

"C:\Program Files\Microsoft SDKs\Windows\v6.0A\bin\SvcUtil.exe" /l:cs /n:*,ims http://127.0.0.1:8080/services/Service?wsdl /out:Service.cs
------------------
上記は URIがhttpになっていますが、実際には下記に示すコードでhttpsにて通信します。
スタブを作成するだけなので、svcutil.exeを使用する際はhttpでOK。


[ -C#- app.config ]
--------------------
<?xml version="1.0" encoding="utf-8"?>
<configuration>
    <configSections>
        <sectionGroup name="applicationSettings" type="System.Configuration.ApplicationSettingsGroup, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" >
            <section name="ca2.Properties.Settings" type="System.Configuration.ClientSettingsSection, System, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
        </sectionGroup>
    </configSections>
    <system.serviceModel>
        <services />
        <bindings>
            <basicHttpBinding>
                <binding name="BasicHttpBinding_Service">
                    <security mode="Transport" />
                </binding>
            </basicHttpBinding>
            <wsHttpBinding>
                <binding name="wsHttpBinding_Service">
                    <security mode="TransportWithMessageCredential">
                        <transport clientCredentialType="None" />
                        <message clientCredentialType="UserName" />
                    </security>
                </binding>
            </wsHttpBinding>
        </bindings>
        <client>
            <endpoint address="https://127.0.0.1:8443/services/Service" binding="basicHttpBinding"
                bindingConfiguration="BasicHttpBinding_Service" contract="ims.IService"
                name="BasicHttpBinding_Service" />
            <endpoint address="https://127.0.0.1:8443/services/Service" binding="wsHttpBinding"
                bindingConfiguration="wsHttpBinding_Service" contract="ims.IService"
                name="wsHttpBinding_Service" />
        </client>
    </system.serviceModel>
    <applicationSettings>
        <ca2.Properties.Settings>
            <setting name="URL" serializeAs="String">
                <value>https://192.168.102.101:443/services/Service</value>
            </setting>
        </ca2.Properties.Settings>
    </applicationSettings>
</configuration>
--------------------
こんなapp.configファイル書けるか!ってな人には、.NET Frameworkに付属しているSvcConfigEditor.exeというツールがありますので、そちらでapp.configファイルを編集してください。Visual Studioにツール登録をしておくと便利です。

詳しくは
http://handcraft.blogsite.org/ComponentGeek/ShowArticle/24.aspx
http://handcraft.blogsite.org/ComponentGeek/ShowArticle/25.aspx

を参照してください。とても参考にさせて頂きました。

SvcConfigEditor.PNG


[ -C#- Program.cs ]
--------------------
using System;
using System.Collections.Generic;
using System.Text;

namespace ca2 {
    class Program {
        static void Main(string[] args) {
            ConfirmCertificatePolicy p = new ConfirmCertificatePolicy(); // 証明書続行確認用
            System.Console.WriteLine("WCFサービスホストを起動したら、キーを入力して下さい。");
            System.Console.ReadLine();
            try {
                ims.ServiceClient proxy = new ims.ServiceClient("BasicHttpBinding_Service",
                    new System.ServiceModel.EndpointAddress(ca2.Properties.Settings.Default.URL));
                Console.WriteLine(proxy.hello());
                proxy.Close();
            } catch (Exception e) {
                Console.WriteLine(e.StackTrace);
            }
            Console.WriteLine("終了するにはなにかキーを押してください。");
            Console.ReadLine();
        }
    }
}
--------------------


[ -C#- ConfirmCertificatePolicy.cs ]
--------------------
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Net;
using System.Net.Security;
using System.Security.Cryptography.X509Certificates;

namespace ca2
{
    class ConfirmCertificatePolicy
    {
        public ConfirmCertificatePolicy()
        {
            ServicePointManager.ServerCertificateValidationCallback += RemoteCertValidation;
        }
        public bool RemoteCertValidation(object sender, X509Certificate cert, X509Chain chain, SslPolicyErrors error)
        {
            if (error != SslPolicyErrors.None)
            {
                Console.WriteLine("証明書に問題があります。理由:" + chain.ChainStatus[0].StatusInformation);
                Console.Write("処理を続行しますか? y:続行:");
                string input = Console.ReadLine();
                if (input.ToLower() == "y")
                    return true;
                else
                    return false;
            }
            return true;
        }
    }
}
--------------------

サンプルとしてはこんな感じかな?


・Windows Server 2003にてプライマリドメインコントローラーを構成。
・WindowsXPをActiveDirectoryに参加させて、ドメインログオン。

以上、普段なんてことのない通常のActiveDirectory環境にて lsasrv spnego negotiator 40960 と msdtc 53258 の警告が「ドメインコントローラー」のイベントログに記録され、クライアントPCからActiveDirectoryのユーザーアカウントで、ドメインログオン出来なくなった。

error1.JPG

error2.JPG

error3.JPG

error4.JPG

error5.JPG

lsasrv spnego negotiator 40960の方は無視出来る(後述)。しかし、 msdtc 53258の方は「MS DTC は、DC 昇格/降格イベントを正しく処理できませんでした。」として警告のメッセージが記録され、おそらく(間違っているかもしれないが)これによりクライアント PCから対話ログオンが出来なくなる。

以下解決した方法。この方法で万全とは言い難いが、memoとしてまとめておく。

- ActiveDirectory PDCにて実行 -

[ ファイル名を指定して実行 ] -> [ cmd.exe] -> [ gpupdate /force ]
として、最新のグループ・ポリシーをシステムに適用させる。

さらに、
[ ファイル名を指定して実行 ] -> [ cmd.exe] -> [ w32tm /config /manualpeerlist:ntpサーバーのIPアドレス,0x8 /syncfromflags:MANUAL ]
として、NTPサーバーを設定(PDCにNTPサーバーが既に設定されていれば、この部分の作業は必要無い)。

その後、

1. [ スタート ] -> [ プログラム ] -> [ 管理ツール ] -> [ コンポーネントサービス ] を順にクリック
2. [ コンソールルート ] -> [ コンポーネントサービス ] -> [ コンピュータ ] -> [ マイコンピュータ ] を右クリックして [ プロパティ ]
3. [ MSDTCタブ ] -> [ セキュリティ構成 ] -> [ ネットワークDTCアクセス ]のチェックを入れ、[ OK ]をクリック。
・再度 2と3を実行し、今度はチェックをOFFにした状態でOKをクリックし、OSを再起動する。

MSDTC.JPG

DTCサービスが正常に起動していることをEvnetLogで確認後、クライアントPCを再起動し、ドメインログオンを試みる。

以上。

---------------
■追記
---------------
kerberosチケットの削除とかも試してみたが、結局DC上にて発生する場合のspnego negotiator 40960は以下のドキュメントを読んで解決とした。

http://support.microsoft.com/kb/824217/ja によると、
「このエラーがサーバーの再起動後にのみ発生する場合は、ディレクトリ サービスの開始前に、サービスが認証を試みている可能性があります。」 とのことなので、無視して良いと思う。

ちなみに Windows Server 2003 のリソースキットはこちらから。
http://www.microsoft.com/downloads/details.aspx?FamilyID=9d467a69-57ff-4ae7-96ee-b18c4790cffd&DisplayLang=en


XP Pro -> ファイルサーバーへアップロード -> XP Pro へダウンロード

というなんてことのない、普通にファイルサーバーへ上げてあるファイルをダウンロードしようとしたら、エラーが出ました。

「ファイルをコピーできません。送り側のファイルまたはディスクから読み取れません。」

...相変わらずエラーメッセージが出ても、ワケが分かりませんね。
しかも、コピー(ダウンロード)出来るファイルもあれば出来ないファイルもあるという困った事態に。

さらにファイルサーバーが MacOS X 10.5 - Leopard - で、中のSambaとiconvが

 init_iconv: Conversion from 932 to UTF-8-MAC not supported

とかふざけたこと言っていやがってですね・・・。
ファイル名はASCII文字列なのに。

結局原因はXPがSP2になった時にZoneIdの付加とかいう仕様変更のためで、インターネットからダウンロードしてきたファイルにセキュリティ情報が 付加されているためでした。

詳しい解説はココ

ダウンロード出来なかったファイルを右クリック -> プロパティ -> 「ブロックの解除」ってボタンを押せばOK。
NTFSだとこーいう問題が起きるので、一旦FATなUSBメモリーにコピーしてから(余計なファイル情報は消してから)NTFSなボリュームへアップ ロードすると良いそうです。

------------------
■追記
------------------
 init_iconv: Conversion from 932 to UTF-8-MAC not supported のエラーは /private/var/db/smb.conf の

 dos charset = 932

 dos charset = CP932
に変更して

$ sudo launchctl unload /System/Library/LaunchDaemons/smbd.plist
$ sudo launchctl load /System/Library/LaunchDaemons/smbd.plist

でSambaを再起動かけたら出なくなりました。
...って当然ですね。orz

iconv -l で確認取ってください。 っていうか、なんで CP932 じゃなくて 932 になってるのよ。

Windowsのクローニング+sysprepについてサラっと。

企業で使うPCだとほとんどがボリュームライセンスもしくはメーカーのOEMライセンスでしょう。
VLの場合はシリアルをそのまま入力でいいのだけど、OEMだと本体シールのシリアル番号を入力してもエラーが出る。
そのためMSでは以下のシリアルを公開しているので、OEMのディスクでインストールする場合は以下のものを使用するといい。

Windows XP Professional 32 ビット版
MVF4D-W774K-MC4VM-QY6XY-R38TB

Windows XP Tablet PC Edition
XT67V-GY7FW-GR6FR-WDK2C-8T97J

Windows XP Professional x64 ビット版
FM634-HJ3QK-6QVTY-RJY4R-XCR9J

詳細は以下のページで
Windows XP を再インストールするときの、OEM の事前ライセンス認証の保持
http://technet.microsoft.com/ja-jp/library/bb457078.aspx

ドメイン環境にあるケースがほとんどだと思うのでインストール後のPC名が重複する場合はあらかじめActiveDirectoryから削除しておくこと。
経験上ウィルス対策ソフトやWSUSのオブジェクトもDBから消しておいたほうがよい。

大雑把な流れは以下のとおり。
・元になるPCへXPをクリーンインストール

・デバイスドライバ、ServicePack、共通のアプリケーションなどをインストール
 ※あとで複製するので、この時ドメインに参加しないこと。SIDが被るので。

・WindowsXPのCD-ROM\SUPPORT\TOOLS\DEPLOY.CAB を解凍

・setupmgr.exe で sysprep.inf を作成
 シリアルと組織名だけ十分。フォルダごとC:\sysprep\ に置いた状態でクローンの元を作成すると楽チン。

クローニングには以下のソフトを使用した。
機能的にはAcronisがいいんだけど有料なのでね・・・

HDD内のデータを丸ごと別HDDへコピーできるフリーソフト「EASEUS Disk Copy」
http://www.forest.impress.co.jp/article/2008/08/26/easeusdiskcopy.html

・EASEUS Disk CopyでCD起動

・USB接続のHDDを認識するので内臓HDD→外付けHDDへとイメージをコピー
 ※PC前面のUSBポートは内蔵のUSBハブを介すので認識しないことがあるので、背面のポートにつけるのが無難かと。

・sysprepの実行
 Miniセットアップにチェックをつけて「再シール」。
 c:\sysprep は実行後削除される。

・ドメインへ参加して完了。

最後にOfficeのライセンスについて。
これも企業ユーザーの多くはeOpenなどのライセンスを使うことになると思う。
ライセンスさえ保有していればそのまま使いたくもなるが、1つのVLのキーでクローニングするとプロダクトキーが重複することになる。

よって以下のレジストリキーを削除して再度シリアルだけ手入力するのがスマート。
HKLM\SOFTWARE\Microsoft\office\11.0\Registration (これはOffice2003)

以下のコマンドでもOK。私の場合はc:\sysprepに入れてからクローニングしてるので、レジストリ削除>sysprep>ドメイン参加としている。
reg delete HKLM\SOFTWARE\Microsoft\office\11.0\Registration /f

こんなエラーが出てグループポリシーが利かなくなった。

イベントの種類: エラー
イベント ソース: AutoEnrollment
イベント カテゴリ: なし
イベント ID: 15
日付:  2009/03/23
時刻:  20:29:11
ユーザー:  N/A
コンピュータ: PC-A
説明:
ローカル システム の証明書の自動登録で、Active Directory (0x8007054b) に連絡できませんでした。指定されたドメインがないか、またはアクセスできません。
 登録は行われません。


イベントの種類: エラー
イベント ソース: Userenv
イベント カテゴリ: なし
イベント ID: 1054
日付:  2009/03/23
時刻:  20:29:10
ユーザー:  NT AUTHORITY\SYSTEM
コンピュータ: PC-A
説明:
コンピュータ ネットワークためのドメイン コントローラ名を取得できません。(指定されたドメインがないか、またはアクセスできません。 )。グループ ポリシーの処理は中止されました。


で、解決方法。
グループポリシーによるMISパッケージの自動インストールのデータが大きすぎてタイムアウトしている場合がほとんどです。。

以下の手順でタイムアウトまでの時間を伸ばせば解決。

1. [スタート] ボタンをクリックし、[ファイル名を指定して実行] をクリックします。「regedit」と入力し、[OK] をクリックします。

2. 次のサブキーを展開します。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon

3. [Winlogon] を右クリックし、[新規] をポイントし、[DWORD 値] をクリックします。
新しい名前として「GpNetworkStartTimeoutPolicyValue」と入力し、Enter キーを押します。

4. [GpNetworkStartTimeoutPolicyValue] を右クリックし、[修正] をクリックします。
[基数] の下の [10 進] をクリックします。

5. [値のデータ] ボックスに「60」と入力し、[OK] をクリックします。

6. レジストリ エディタを終了し、コンピュータを再起動します。

7. グループ ポリシーのスタートアップ スクリプトが実行されない場合は、GpNetworkStartTimeoutPolicyValue レジストリ エントリの値を増やします。

各マシンのレジストリをイチイチ変更するなんてやってられん!という場合イベントビューワにDHCPのエラーが出ていないか確認する必要あり。
DHCPからIPアドレスの取得に時間がかかっている場合などはイベントビューワに1003や1007の警告が出る。

今回の場合、
DHCPサーバー>スイッチ>スイッチ>スイッチ>PCだとNG。
DHCPサーバー>スイッチ>スイッチ>PCだとOKという変な状態に。
結局真ん中に挟まっていたスイッチをリスタートして完了。

調べてみるとルーターやらスイッチがラリっているケースが少なくないようです。

別のトラブルを追跡中に netdiag /test:keberos したらこんなん出ました。

Kerberos test. . . . . . . . . . . : Failed
        [FATAL] Kerberos does not have a ticket for host/PC.test.local.

klist purge

として一度Keberosのチケットを削除したらPassになりました。
なんでこーなったのかは不明・・・

klist.exe はこちらから

GPO適用時にエラーだったらメールを飛ばす...とか色々と使えそうなのでmemoしておきます。

Gmailとか、外部のSMTP鯖も使えます。Googleから何か言われるかもしれませんが。
以下ソース。

[ mail.vbs ]
---------------------
Option Explicit

Sub mail_send()
    Dim oMsg
    Dim schemas

    Set oMsg = CreateObject("CDO.Message")
    schemas = "http://schemas.microsoft.com/cdo/configuration/"

    oMsg.From = "hogefuga@gmail.com"
    oMsg.To = "test@example.com"
    oMsg.Subject = "Test "
    oMsg.TextBody = "テストメッセージです" & vbCrLf & Now

    oMsg.Configuration.Fields.Item(schemas + "sendusing") = 2
    oMsg.Configuration.Fields.Item(schemas + "smtpusessl") = true
    oMsg.Configuration.Fields.Item(schemas + "smtpauthenticate") = true
    oMsg.Configuration.Fields.Item(schemas + "sendusername") = "hogefuga@gmail.com"
    oMsg.Configuration.Fields.Item(schemas + "sendpassword") = "password"
   
    oMsg.Configuration.Fields.Item(schemas + "smtpserver") = "smtp.gmail.com"
    oMsg.Configuration.Fields.Item(schemas + "smtpserverport") = 25
    oMsg.Configuration.Fields.Update

    oMsg.Send
End Sub

mail_send
[ EOF ]
---------------------


Express EditionでもWindowsサービスの作成は可能です。
以下にサンプルを示します。

[ Program.cs ]
------------------
using System;
using System.Collections.Generic;
using System.Text;
using System.ServiceProcess;

/* System.ServiceProcess.ServiceBaseを継承 */
namespace IntraMasterService {
    class Program : ServiceBase {

        static void Main(string[] args) {
            System.ServiceProcess.ServiceBase[] ServicesToRun = new System.ServiceProcess.ServiceBase[] { new Program() };
            System.ServiceProcess.ServiceBase.Run(ServicesToRun);
            Console.ReadLine();
        }
        protected override void OnStart(string[] args) {
            base.OnStart(args);
            /* ここにサービス開始時の処理を記述する */
            /* Thred.Timerなどで処理を振り分けたり、色々出来ます */
        }
        protected override void OnStop() {
            base.OnStop();
            /* ここにサービス停止時の処理を記述する */
        }
    }
}
[ EOF ]
------------------

さらに、.NET Framework Runtimeに同梱されている InstallUtil.exeにてWindowsサービスの登録を行うために、Installerクラスを継承したサブクラスを用意します。

[ ProjectInstaller.cs ]
------------------
using System;
using System.Collections;
using System.Configuration.Install;
using System.ServiceProcess;
using System.ComponentModel;

[RunInstallerAttribute(true)]
public class ProjectInstaller : Installer {

    private ServiceInstaller serviceInstaller;
    private ServiceProcessInstaller processInstaller;

    // 以下にこのプロジェクトが依存するサービスを記述
    private string[] param = new string[] { "SENS", "Eventlog", "Nla", "RpcSs", "winmgmt", "Netlogon" };

    public ProjectInstaller() {
        processInstaller = new ServiceProcessInstaller();
        serviceInstaller = new ServiceInstaller();

        // Service will run under system account
        processInstaller.Account = ServiceAccount.LocalSystem;

        // Service will have Start Type of Automatic
        serviceInstaller.StartType = ServiceStartMode.Automatic;
       
        this.setOsVersion();

        serviceInstaller.ServicesDependedOn = this.param;
        serviceInstaller.ServiceName = "IntraMaster";
        serviceInstaller.Description = "PCの情報を集めてサーバーに報告します";

        Installers.Add(serviceInstaller);
        Installers.Add(processInstaller);
    }
    private void setOsVersion() {
        //string[] parm = new string[] { "SENS", "Eventlog", "Nla", "RpcSs", "winmgmt" };

        System.OperatingSystem os = System.Environment.OSVersion;
        switch (os.Platform) {
            case PlatformID.Win32Windows:
                //Console.WriteLine("OSは Windows 95 以降です。");
                if (os.Version.Major >= 4) {
                    switch (os.Version.Minor) {
                        case 0:
                            //Console.WriteLine("OSは Windows 95 です。");
                            break;
                        case 10:
                            //Console.WriteLine("OSは Windows 98 です。");
                            break;
                        case 90:
                            //Console.WriteLine("OSは Windows Me です。");
                            break;
                    }
                }
                break;
            case PlatformID.Win32NT:
                //Console.WriteLine("OSは Windows NT 以降です。");
                switch (os.Version.Major) {
                    case 3:
                        switch (os.Version.Minor) {
                            case 0:
                                //Console.WriteLine("OSは Windows NT 3 です。");
                                break;
                            case 1:
                                //Console.WriteLine("OSは Windows NT 3.1 です。");
                                break;
                            case 5:
                                //Console.WriteLine("OSは Windows NT 3.5 です。");
                                break;
                            case 51:
                                //Console.WriteLine("OSは Windows NT 3.51 です。");
                                break;
                        }
                        break;
                    case 4:
                        if (os.Version.Minor == 0) {
                            //Console.WriteLine("OSは Windows NT 4.0 です。");
                        }
                        break;
                    case 5:
                        if (os.Version.Minor == 0) {
                            //Console.WriteLine("OSは Windows 2000 です。");
                        } else if (os.Version.Minor == 1) {
                            //Console.WriteLine("OSは Windows XP です。");
                        }
                        break;
                    case 6:
                        if (os.Version.Minor == 0) {
                            //Console.WriteLine("OSは Windows Vista です。");
                            this.param = new string[] { "SENS", "Eventlog", "NlaSvc", "RpcSs", "Winmgmt", "Netlogon" };
                        }else if(os.Version.Minor == 1){
                            this.param = new string[] { "SENS", "Eventlog", "NlaSvc", "RpcSs", "Winmgmt"};
                        }
                        break;
                }
                break;
            case PlatformID.Win32S:
                //Console.WriteLine("OSは Win32s です。");
                break;
            default:
                //Console.WriteLine("(不明)");
                break;
        }
    }
}
[ EOF ]
------------------

このページの先頭へ