Windows7のデスクトップショートカットが削除される

Windows7のコントロールパネルにある「トラブルシューティング→設定の変更」にて、コンピューターの保守が有効になっている場合、定期的にスクリプトが動作してクリック先ファイルの見つからないショートカットや、一定期間使用していないデスクトップアイコンを自動的に削除します。

Google等で検索すると、対処方法として「コントロールパネルの設定で無効にする」とか、「レジストリのLinkResolvelgnoreLinkInfo、NoResolveTrack、NoResolveSearchを無効に設定する」とか、「TS_BrokenShortcuts.ps1を編集する」といった回答がヒットします。これらは当時緊急に模索された方法です。現在は解決方法としてMicrosoftからKB2642357が提供されいてるので、この情報にしたがって対応するのがよいでしょう。

解決方法は「KB2642357 :Broken shortcuts are deleted from the desktop in Windows 7(日本語訳は機械翻訳の質がすごく悪いので英語を読んだほうがよい)」に記載されています。ここで提供されているHotFixをダウンロードしてインストールしてから、記載内容にしたがってレジストリを編集します。

インストール手順

HotFixのダウンロードURLは公開されていないので、ダウンロードボタンをクリックした後、メールアドレスを入力してCAPTCHAによる認証を行います。その後、登録したメールアドレスにダウンロードURLを記載したメールが送られてくるので、そこからダウンロードします。

ダウンロードしたファイルは自己解凍の圧縮ファイルになっているので、適当なフォルダに解凍します。 解凍したWindows6.1-KB2642357-x86.msuをダブルクリックしてインストールします。

合わせて以下のレジストリ値を作成して設定します。

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\ScheduledDiagnostics]
"IsBrokenShortcutsTSEnabled"=dword:00000000
"IsUnusedDesktopIconsTSEnabled"=dword:00000000

グループポリシーでの展開方法

グループポリシーから行う場合には、Windows6.1-KB2642357-x86.msuをスタートアップスクリプトでインストールします。Windows6.1-KB2642357-x86.msuを共有フォルダに配置しておき、Windows Update Standalone Installer(wusa.exe)を呼び出す次のようなBATファイルを作成します。これをグループポリシーの「コンピューターの構成→ポリシー→Windowsの設定→スクリプト」にてスタートアップスクリプトに登録します。

@ECHO OFF
SET LOGFILE=%SystemRoot%\Logs\Windows6.1-KB2642357-x86.log

IF EXIST %LOGFILE% GOTO EXIT
md %SystemRoot%\Logs
echo "Windows6.1-KB2642357-x86.msuを適用しました。" > %LOGFILE%
wusa.exe "\\adsv\share\HotFix\Windows6.1-KB2642357-x86.msu" /quiet /warnrestart

:EXIT

合わせてレジストリの設定も必要になるので、グループポリシーの「コンピューターの構成→基本設定→Windowsの設定→レジストリ」にてIsBrokenShortcutsTSEnabledとIsUnusedDesktopIconsTSEnabledを作成するように設定します。

Adobe Flashをグループポリシーで配布するには

Adobe FlashをActive Dierctoryのグループポリシーで配布する手順をメモ

1.再配布ライセンスの取得手続き

Adobe Readerの再配布にはAdobeランタイム/Reader配布許諾契約(https://distribute.adobe.com/mmform/index.cfm?name=distribution_form&pv=fp&loc=ja)が必要です。リンク先のWEBページにて手続きをしてください。手続きを終えるとメールが送られてきます。

2.インストーラーのダウンロード

送られてきたメールにインストーラのダウンロードURLが掲載されています。当該サイトからMSI形式のインストーラをダウンロードします。

3.グループポリシーに登録する

MSIファイルが確保できれば後は簡単ですね。クライアントパソコンからアクセス可能な共有フォルダにMSIファイルを配置して、グループポリシーの「コンピューターの構成→ポリシー→ソフトウェアの設定→ソフトウェアインストール」にMSIファイルを設定すれば配布できます。

Adobe Reader DCをグループポリシーで配布するには

Adobe ReaderをActive Dierctoryのグループポリシーで配布する手順をメモ

1.再配布ライセンスの取得手続き

Adobe Readerの再配布にはAdobeランタイム/Reader配布許諾契約(https://distribute.adobe.com/mmform/index.cfm?name=distribution_form&pv=fp&loc=ja)が必要です。リンク先のWEBページにて手続きをしてください。手続きを終えるとメールが送られてきます。

2.Adobe Reader DCをダウンロードします
Adobe Acrobat Reader DCの配布(http://get.adobe.com/jp/reader/enterprise/)からOSの種類や言語を選んでインストーラをダウンロードします。

3.インストーラを解凍して共有フォルダに置

Adobe Readerのインストーラは7z形式の自己解凍圧縮ファイルとして作成されています。7zを扱える解凍ツールを使うと、インストーラに含まれているファイルを解凍する事でMSIファイルを得る事ができます。

4.グループポリシーに登録する

解凍したファイルをクライアントPCから参照可能な共有フォルダに配置します。 グループポリシーの「コンピューターの構成→ポリシー→ソフトウェアの設定→ソフトウェアインストール」にMSIファイルを設定すれば配布できます。

5.インストーラ修正プログラムの配布

このままだとバージョンのAdobe Readerがインストールされるだけで、最新のパッチは適用されません。先ほど解凍したファイルに含まれているインストーラー修正プログラム(MSPファイル)もインストールする必要があります。MSPファイルはスタートアップスクリプトから起動してインストールします。

ログファイルが作成されていなければインストールされるように、次のようなバッチファイルを作成して「C:\Windows\SYSVOL\sysvol\\scripts」などに配置します。

@ECHO OFF
SET LOGFILE=%SystemRoot%\Logs\AcroRdrDCUpd1500820082.log
SET ERRFILE=%SystemRoot%\Logs\AcroRdrDCUpd1500820082.err

ECHO "ログファイルの有無でインストール状況を判定し、インストーラを起動する"
IF EXIST LOGFILE GOTO EXIT
msiexec.exe /p "\\adsv\INSTALL\AdobeReader\AcroRdrDCUpd1500820082.msp" /qn /log %ERRFILE%

IF NOT ERRORLEVEL 0 GOTO EXIT
RENAME %ERRFILE% *.log

:EXIT

グループポリシーの「コンピューターの構成→ポリシー→Windowsの設定→スクリプト」のスタートアップに作成したバッチファイルを設定すればパッチが適用されます。

Java Runtimeをグループポリシーで配布するには

JREをActive Dierctoryのグループポリシーで配布する手順をメモ

1. インストーラのダウンロード

Java SEのDownloadサイトからJREをダウンロードする。ダウンロードするファイルはオフラインインストール用の実行ファイル(jre-8u60-windows-i586.exe、jre-8u60-windows-x64.exe)をダウンロードする。配布対象が32bit OSであればjre-8u60-windows-i586.exeだけでよい。jre-8u60-windows-x64.exeに32bit版ブラウザ用のプラグイン等が含まれていないため、64bit OSに配布する場合には jre-8u60-windows-i586.exe、jre-8u60-windows-x64.exeの両方が必要になる。

2.MSIファイルを取り出す

ダウンロードした実行ファイルを起動してインストール確認画面が表示されているときに、C:\Users\ユーザー名\AppData\LocalLow\Oracle\Java\以下を参照するとMSIファイルが作成されます。このMSIファイルをコピーして、グループポリシーからのインストールに使用します。なんと、これ、公式の手順です。「Active Directory を使用する JRE の配備(http://docs.oracle.com/javase/jp/7/technotes/guides/deployment/deployment-guide/install-msi.html)

3.グループポリシーに登録する

MSIファイルが確保できれば後は簡単ですね。クライアントパソコンからアクセス可能な共有フォルダにMSIファイルを配置して、グループポリシーの「コンピューターの構成→ポリシー→ソフトウェアの設定→ソフトウェアインストール」にMSIファイルを設定すれば配布できます。
配布対象が64bit OSの場合は、32bit版のJREと、64bit版のJREの両方をインストールする必要がある事に注意してください。

Windows10のディスクアクセス負荷が高い場合の対処

Windows10が妙に重たいので調べてみた。

タスクマネージャーでパフォーマンスの項目を見ると、Cドライブのアクティブな時間がほぼ100%になっており、平均的な応答時間に数千msかかっている状態になっている。C:に使用しているHDDが低速だと、このような状態になりやすい。このような症状はCPU負荷はそれほど高くないので原因の特定が難しい。
Windows10_disk_busy

この場合、実は意外なところの設定でディスクへのアクセス負荷が大きく下がる。スタートメニューから設定→パーソナル設定→色にある「背景からアクセントカラーを選ぶ」「スタート、タスクバー、アクションセンターに色をつける」「スタート、タスクバー、アクションセンターを透明にする」のトグルスイッチをオン→オフに切り替えるとディスクアクセス負荷が驚くほど下がる。
windows10_color_config

もし古いパソコンにWindows10をインストールして使用しているのであればお試しあれ。

SymmetricDSで日本語の使えない機能

SQL Server 2000とSQL Server 2012のデータ連係(SymmetricDS)で日本語を使えると書いたが、機能しない機能も見つかってきたので覚書。

同期条件の指定(Sync On ~ Condition)

SYM_TRIGGERテーブルのSYNC_ON_UPDATE_CONDITION、 SYNC_ON_INSERT_CONDITION、 SYNC_ON_DELETE_CONDITIONには日本語カラム名を含む条件式を指定できない。SYNC_ON_~_CONDITIONは同期対象のカラムを限定する制約条件を指定する事の出来るパラメーターだが、日本語を含むカラム名をしていすると、トリガーの登録時にエラーログにカラムが見つからない旨のエラーが記録される。
これはSymmetricDSのサンプルにおいても使われている機能です。サンプルも一部動かないので気を付けよう。

SQL Server 2000からSQL Server 2012への移行

レガシーマイグレーションというほどでは無いが、古いWindows 2003 ServerをWindows 2012 Serverに移行するにあたって覚え書き。

SQL Server 2000のデータベースをSQL Server 2012でマウントする事は出来ません。SQL SerSQL Server 2005のデータベースをSQL Server 2014でマウントする事は出来ません。したがってSQL Server 2000や2005から互換性がないSQL Serverにデータを移行するには、いったんSQL Server 2008を経由する必要があります。

SQL Serverのデータフォルダ(既定では%PROGRAM FILES%¥Microsoft SQL Server¥MSSQL¥Data)にあるMDFファイルとLDFファイルをSQL Server 2008の環境にコピーします。

SQL Server 2008上でコピーしたMDFファイルとLDFファイルをアタッチしてデータベースを起動します。

互換性レベルが80(SQL Server 2000)ないし90(SQL Server 2005)になっているので、100(SQL Server 2008)に変更します。これで先ほどアタッチしたMDFファイルとLDFファイルのバージョンが上がります。

SQL Server 2008上のMDFファイルとLDFファイルを、移行先となるSQL Server 2012またはSQL Server 2014にコピーしてアタッチします。

最終移行先となるSQL Server上で再び互換性レベルを変更します。110(SQL Server 2012)または120(SQL Server 2014)に変更します。

以上でデータの移行は完了。

念のために移行後のデータベースに「DBCC CHECKDB(~)」をかける。変換時に不整合が発生したり、互換性の無い機能が含まれていて問題になることもある。もしエラーになるなら、速やかに修正する。

データのインポートおよびエクスポートウィザードを使用する方法考えられるが、SQL Server Native Clientなどでは接続できないため、OLE DB Providerやフラットファイルソースを使用する事になる。この場合テーブル自体はインポートできるが、テーブルに付属するインデックス情報や制約情報、ビュー、ストアドプロシージャなどは取込むことが出来ない。テーブルデータ以外は別途SQL文として取得して、移行先のSQL Serverで実行することになる。手間を考えるとデータベースのバイナリファイルを直接移動する方が良いと思う。

SQL Server 2000とSQL Server 2012のデータ連係(SymmetricDS)

せめてSQL Server 2005とSQL Server 2012であればリプリケーションを使って、片側のデータベースに対する更新を、もう片方のデータベースに反映して同期を取ることも出来るのだけど・・・と、良い方法を探していたところSymmetricDS(http://www.symmetricds.org/)というリプリケーションツールを見つけた。

SymmetricDSはJava SE6以上が動作するOSで、JDBCで接続可能なデータベース間であれば、およそ殆どの異なるアーキテクチャ間のDBを双方向にリプリケーション出来る優れものです。SQL Server 2000でも動作するはずなので、今回の用途にはぴったりです。さっそく試験環境を作成してテストしてみましょう。

1.SymmetricDSのインストール

1.1.SymmetricDSのダウンロード

SymmetricDSのホームページからzipファイルをダウンロードして、インストール先に解凍します。ここではC:\App\symmetricに解凍することにします。

1.2.ルートノードの設定ファイルを作成する

データベースへの接続設定を作成します。データベースへの接続に関する設定はC:\App\symmetric\enginesに保存します。C:\App\symmetric\samplesからcorp-000.propertiesを複製して設定します。今回はrootnode.propertiesという名称にします。

engine.nameには任意の名称を指定します。今回はrootnodeとします。

db.driverにはJDBCドライバの名称を指定します。デフォルトではH2 Databaseが指定されているので、これをコメントにしてnet.sourceforge.jtds.jdbc.Driverのコメントを外します。

db.urlには同期するデータベースへの接続文字列を指定します。デフォルトではH2 Databaseが指定されているので、これをコメントにしてjdbc:jtds:sqlserver://localhost:1433/rootdb;useCursors=true;bufferMaxMemory=10240;lobBuffer=5242880;に変更します。rootdbはデータベース名ですが、ここには日本語を指定できません。

db.userにはデータベースへのログインIDを指定します。本来はSymmetricDS用にアカウントを作るべきですが、今回はsaを指定しておきます。

db.passwordには先のログインIDで使用するパスワードを指定します。

sync.urlには同期に使用するHTTP URLを指定します。ここではhttp://localhost:31415/sync/rootnodeと指定します。sync移行に続く文字列はengine.nameで指定した文字列と一致しなくてはなりません。

group.idとexternal.idは、SymmetricDS上でデータベースを一位に識別するためのIDを指定します。ここではgroup.idをrootnode、external.idを000としておきます。

他にもパラメータがありますが、そのままにしておきます。

engine.name=rootnode

# The class name for the JDBC Driver
...#db.driver=org.h2.Driver
db.driver=net.sourceforge.jtds.jdbc.Driver

# The JDBC URL used to connect to the database
...
#db.url=jdbc:h2:corp;AUTO_SERVER=TRUE;LOCK_TIMEOUT=60000
db.url=jdbc:jtds:sqlserver://localhost:1433/rootdb;useCursors=true;bufferMaxMemory=10240;lobBuffer=5242880;

# The user to login as who can create and update tables
db.user=sa

# The password for the user to login as
db.password=xxxxxx

registration.url=
sync.url=http://localhost:31415/sync/rootdb

# Do not change these for running the demo
group.id=rootnode
external.id=000

1.3.同期対象となるノードの設定ファイルを作成する

データベースへの接続設定を作成します。データベースへの接続に関する設定はC:\App\symmetric\enginesに保存します。C:\App\symmetric\samplesからstore-000.propertiesを複製して設定します。今回はsubnode-000.propertiesという名称にします。

engine.nameには任意の名称を指定します。今回はsubnode-001とします。

db.driverにはJDBCドライバの名称を指定します。ルートノードと同じくデフォルトではH2 Databaseが指定されているので、これをコメントにしてnet.sourceforge.jtds.jdbc.Driverのコメントを外します。

db.urlには同期するデータベースへの接続文字列を指定します。ルートノードと同じくデフォルトではH2 Databaseが指定されているので、これをコメントにしてjdbc:jtds:sqlserver://localhost:1433/subdb01;useCursors=true;bufferMaxMemory=10240;lobBuffer=5242880;に変更します。

db.userにはデータベースへのログインIDを指定します。本来はSymmetricDS用にアカウントを作るべきですが、今回はsaを指定しておきます。

db.passwordには先のログインIDで使用するパスワードを指定します。

registration.urlにはルートノードsync.urlの値を指定します。ここではhttp://localhost:31415/sync/rootnodeと指定します。

group.idとexternal.idをルートノードと同様に設定します。ここではgroup.idをsubnode、external.idを001としておきます。

他にもパラメータがありますが、そのままにしておきます。

engine.name=subnode-001

# The class name for the JDBC Driver
...#db.driver=org.h2.Driver
db.driver=net.sourceforge.jtds.jdbc.Driver

# The JDBC URL used to connect to the database
...
#db.url=jdbc:h2:corp;AUTO_SERVER=TRUE;LOCK_TIMEOUT=60000
db.url=jdbc:jtds:sqlserver://localhost:1433/subdb01;useCursors=true;bufferMaxMemory=10240;lobBuffer=5242880;

# The user to login as who can create and update tables
db.user=sa

# The password for the user to login as
db.password=xxxxxx

registration.url=http://localhost:31415/sync/rootdb

# Do not change these for running the demo
group.id=subnode
external.id=001

1.4.ルートノードに制御テーブルを作成する

次のコマンドを実行してルートノードのデータベースに制御テーブルを作成します。これによりデータベースにsym~で始める各種テーブルが作成されます。制御テーブルは別のデータベースに作りたいと思うかもしれませんが、ルートノードで指定したデータベース以外の場所に作ることはできないようです。

bin\symadmin --engine rootnode create-sym-tables

続いてデータベース間の同期方法に関する設定を、上記コマンドで作成されたテーブルにINSERTします。

--既存の設定を削除。sym_channelには既定のテーブルがあるので、作成したものだけ削除するようになっています。
delete from sym_trigger_router;
delete from sym_trigger;
delete from sym_router;
delete from sym_channel where channel_id in ('tblcopy');
delete from sym_node_group_link;
delete from sym_node_group;
delete from sym_node_host;
delete from sym_node_identity;
delete from sym_node_security;
delete from sym_node;

--テーブルのコピーに使用するチャンネルを作成。
--同期でエラーが発生すると、同じチャンネルを使用しているその他の複製処理もエラーが回復するまで待たされます。
--エラーが発生しても並列して複製処理を行いたい場合には、チャンネルを複数作成します。
insert into sym_channel (channel_id, processing_order, max_batch_size, enabled, description)
values('tblcopy', 1, 100000, 1, 'Copy Sample Table');

insert into sym_node_group (node_group_id) values ('rootnode');
insert into sym_node_group (node_group_id) values ('subnode');

insert into sym_node_group_link (source_node_group_id, target_node_group_id, data_event_action) values ('rootnode', 'subnode', 'W');
insert into sym_node_group_link (source_node_group_id, target_node_group_id, data_event_action) values ('subnode', 'rootnode', 'P');

--複製の対象テーブルや複製を開始する判断条件を指定します。
--ここではワイルドカードで全てのテーブルを複製するように指定して、それ以外の項目は規定値にしています。
insert into sym_trigger
(trigger_id,source_table_name,channel_id,last_update_time,create_time)
values('tblcopy','*','tblcopy',current_timestamp,current_timestamp);

--複製の方向の指定と、複製するデータのフィルタ条件を指定します。
--複製する条件はdefaultとして全てを複製するように指示しています。
insert into sym_router (router_id,source_node_group_id,target_node_group_id,router_type,create_time,last_update_time)
values('root_2_sub', 'rootnode', 'subnode', 'default',current_timestamp, current_timestamp);
insert into sym_router (router_id,source_node_group_id,target_node_group_id,router_type,create_time,last_update_time)
values('sub_2_root', 'subnode', 'rootnode', 'default',current_timestamp, current_timestamp);

--sym_triggerとsym_routerを関連付けています。
insert into sym_trigger_router
(trigger_id,router_id,initial_load_order,last_update_time,create_time)
values('tblcopy','root_2_sub', 100, current_timestamp, current_timestamp);

--ノードの登録を行います。
insert into sym_node (node_id,node_group_id,external_id,sync_enabled,sync_url,schema_version,symmetric_version,database_type,database_version,heartbeat_time,timezone_offset,batch_to_send_count,batch_in_error_count,created_at_node_id)
values ('000','rootnode','000',1,null,null,null,null,null,current_timestamp,null,0,0,'000');
insert into sym_node (node_id,node_group_id,external_id,sync_enabled,sync_url,schema_version,symmetric_version,database_type,database_version,heartbeat_time,timezone_offset,batch_to_send_count,batch_in_error_count,created_at_node_id)
values ('001','subnode','001',1,null,null,null,null,null,current_timestamp,null,0,0,'000');

insert into sym_node_security (node_id,node_password,registration_enabled,registration_time,initial_load_enabled,initial_load_time,created_at_node_id)
values ('000','5d1c92bbacbe2edb9e1ca5dbb0e481',0,current_timestamp,0,current_timestamp,'000');
insert into sym_node_security (node_id,node_password,registration_enabled,registration_time,initial_load_enabled,initial_load_time,created_at_node_id)
values ('001','5d1c92bbacbe2edb9e1ca5dbb0e481',1,null,1,null,'000');

--ルートノードのnode_idを指定します。ルートノードは1つだけ作成します。
insert into sym_node_identity values ('000');

1.5.SymmetricDSを起動する

次のコマンドを実行してSymmetricDSを起動します。

bin\sym

正常に起動した場合、sym_~で指定したテーブルや、rootdbにある同期対象のテーブルがsubdb01に複製されデータの同期が開始されます。

2.その他TIPSなど

2.1.日本語への対応

日本語で作成したテーブル名やフィールド名があっても正常に動作しているようです。
ただしデータベース名に日本語を使用する場合はdb.urlで指定することができないので、データベースで使用するユーザーアカウントの既定のデータベースでデータベース名を指定する等の対応が必要になります。

2.2.設定に誤りがあった場合の訂正

設定に誤りがあった場合、テーブルを直接書き換えても認識して動作が変わるのですが、各テーブルに作成された中間データとの整合性が取れなくなる場合があるようで、設定が反映されない場合があります。この場合は”bin/symadmin –engine uninstall”のコマンドを実行して制御テーブルを削除し、あらためて作り直した方がよいです。

2.3.Microsoft製JDBCドライバの使用

Microsoft製JDBCドライバでも問題なく動作しています。
ただしSymmetricDSの開発サイドではjtdsのドライバを使用して動作確認しているとの事なので、そちらを利用したほうがよいでしょう。

Windows Vista以降でサービスから画面を表示する

Windows VISTA以降のWindowsではセッション0分離の機能により、サービスから直接UIを表示することができなくなりました。Microsoftの互換性情報では代替手段として「ユーザーログイン時に常駐プロセスを起動しサービスと通信を行う。」「WTSSendMessage関数を使用してメッセージボックス相当の表示を行う。」「CreateProcessAsUserを使用してログインユーザー権限でアプリケーションを起動する。」の三つの方法が提示されています。ここでは最後の「CreateProcessAsUserを使用してログインユーザー権限でアプリケーションを起動する。」サンプルを提示します。
サービスから画面を表示するにはRemote Desktop Services APIを使用します。
WTSGetActiveConsoleSessionId関数で物理コンソールのセッションIDを取得します。
WTSQueryUserToken関数で取得したセッションIDのユーザートークンを取得します。
DuplicateTokenEx関数で取得したユーザートークンを複製し、プライマリトークンを作成します。
CreateEnvironmentBlockを使用してユーザーの環境変数を取得します。
CreateProcessAsUser関数を使用して画面を表示するプロセスを起動します。

BOOL    bRet(FALSE);
HANDLE  hUserToken(INVALID_HANDLE_VALUE);
if (::WTSQueryUserToken(WTSGetActiveConsoleSessionId(), &hUserToken))
{
    SECURITY_ATTRIBUTES sa;
    memset(&sa, 0x00, sizeof(sa));
    sa.nLength	= sizeof(SECURITY_ATTRIBUTES);
    HANDLE	hDupedToken(INVALID_HANDLE_VALUE);
    if (::DuplicateTokenEx(hUserToken, 0, &sa, SecurityIdentification, TokenPrimary, &hDupedToken))
    {
        PVOID	lpEnvironment(NULL);
        if (::CreateEnvironmentBlock(&lpEnvironment, hUserToken, FALSE))
        {
            STARTUPINFO stStartUpInfo;
            memset(&stStartUpInfo, 0, sizeof(STARTUPINFO));
            stStartUpInfo.cb        = sizeof(STARTUPINFO);
            stStartUpInfo.lpDesktop = _T("winsta0¥¥default");
            PROCESS_INFORMATION ProcessInfo;
            memset(&ProcessInfo, 0, sizeof(PROCESS_INFORMATION));
            ::CreateProcessAsUser(hDupedToken, _T(""), (char*)(const char*)strCmd, NULL, NULL
                    , FALSE, CREATE_UNICODE_ENVIRONMENT, lpEnvironment, NULL, &stStartUpInfo, &ProcessInfo);
        }
    }
}

感染した未知のコンピュータウィルスを削除するには・・・実践編2/2

続いてレジストリの確認を取ります。実践編1/2でウィルスが起動しないようにしたあと、for VirusCheck OSを起動して、レジストリエディタから全レジストリの内容をエクスポートします。エクスポートしたレジストリはテキストファイルイン保存されますので、for Refrence OSのウィルス感染前のレジストリをエクスポートしたものと比較して変更箇所を検証していきます。
registry
実際に細かく追っていくとかなり根気のいる作業です。今回のウィルスでは以下の場所に改変がくわえられ、ログオン時にウィルスが起動されるようになっていました。

[HKEY_LOCAL_MACHINE&yenSOFTWARE&yenMicrosoft&yenWindows NT&yenCurrentVersion&yenWinlogon]
“Userinit”=”C:&yen&yenWINDOWS&yen&yensystem32&yen&yenuserinit.exe,C:&yen&yenProgram Files&yen&yenCommon Files&yen&yensvchost.exe -s”

今回のウィルスは比較的シンプルな作りになっていたので、ファイル1つ、レジストリ1箇所だけで済んでいます。etcやDNSサーバの情報を改ざんしたり、電子証明書を改ざんしたり、ドライバを組み込んだり、ブラウザやエクスプローラーにプラグインを組み込んだりと、複雑な動作をするウィルスもいます。気を抜かずに根気よく一つ一つ確認していく事が重要です。
ウィルスを駆除する為に削除するファイルやレジストリが明確になったら、実際に感染した環境でそれらのファイルを削除したり、あるいはレジストリを修復していく事になります。ウィルスが常駐している状態では削除などの操作はウィルスによってトラップされており、おこなえないのが常です。OSのモジュールの一部が置き換えられている場合には、たとえセーフモードで起動したとしてもウィルスは常駐してしまいます。KNOPPIXなどのCDからブートするLinux環境から、NTFSのファイルシステムをマウントして、ファイルの削除などをおこなうのが一番確実でしょう。
今回のウィルスは幸いな事に、セーフモードのコマンドプロンプトで起動すれば、ウィルスが常駐する事を防げます。したがってセーフモードのコマンドプロンプトで起動した後、C:¥Program Files¥Common Files¥svchost.exeのシステム属性と非表示属性を解除し、ファイルを削除することで除去できました。