読者です 読者をやめる 読者になる 読者になる

ゲストOSのCPUとメモリの節約をするには

どう考えるか?私は集約化もそうですがESXを安定化させるにはゲストOSのCPUとメモリの節約をすることとキャッシュを出来るだけ有効化することが重要と考えます。正直なところ、ブートストーム対策としては各種キャッシュ、Storage Accelaratorやストレージそのもののキャッシュが非常に有効です。

もう少ししたら今構築中のNetAppでのSSDをキャッシュとして利用する場合のスペック測定が出来ますので、そちらで触れさせて頂きます。正直なところオールフラッシュにしてしまえば関係ありませんが、日本HPがSSDの発注先をIntelだけにすることで低下価格化するという発表もされましたので、安価に構築する場合でも高スペックな環境が組みやすくなってきていることは間違いないと思います。

さて、本題ですが効率的にVDIのCPUとメモリリソースを削減するには、ですがそんな難しいことは行いません。利用者が意図しないプロセスが動かないようにするだけです。そのためには、例えば画面での無駄な処理としてガジェット(そもそもMSがサポート打ち切っている)、エアロ、フォントのスムージングなどを無くし、出来るだけWindowsXPライクに近づける事。次に、音声系ですが例えばログイン時のサウンドやエラー音などですが、事務作業中にそんなの必要ですか?必要ないですよね?ということはこれらもある意味不要。次にサービス関係、例えばWindows Defender、デフラグ、ブランチキャッシュ等々です。また、VDIですので常時ウィルススキャンは必須ですがVDI上で実行するとvCPU2にしてメモリ割り当ても32bitの場合でも2GBから3GBに増やす必要が出るでしょう。そういった観点からvShiled EndPoint(今はNSXに統合されたり機能制限されている)を利用するとユーザが利用する際にバックグラウンドで動作するプロセスによるもたつきやラグを抑えることが可能となります。

pc管理に便利なツール

VDI触れなさいよ、という意見が出る時期だと思いますが設定しているポリシーとか棚卸ししないといけないのでそれまでの閑話休題的なものと思ってください。

私がよく使うツールでpsexec pslist pskillがあります。

https://technet.microsoft.com/ja-jp/sysinternals/pxexec.aspx

どれもコマンドプロンプトで実行するツールですが、psexecは接続先にコマンドを発行させるツール、pslistは接続先の稼働中のプロセスをリストアップするツール、pskillは接続先のプロセスをプロセスID指定で終了させるツールです。

psexecは兎も角pslist /pskillが何故挙げられたかですが、office20xxを利用されていると良くあると思いますがExcelが特に応答なしになってタスクマネージャーでもプロセスが終了できないケースがあると思います。そういったときにpslistで対象アプリのプロセスIDを確認しpskillで終了させると即落ちます。

これらツールに関してですがWindowsfirewallが停止している場合でも以下の点に注意が必要です。

1: これらのツールを利用するときは接続先、接続元両方で管理者権限が必要

→要するに右クリックの別のアカウントで実行からdomain admin等でのコマンドプロンプトの実行するかDomain administratorでのログインが必要になります。

また、ドメイン参加しているPCからworkgroupのPCへ接続する場合はローカルAdministratorのパスワードを合わせてドメイン参加PCにローカルAdministratorアカウントで実行すれば接続可能です。
2.リモートプロシージャコールのサービスがデフォルトでは停止していると思いますが、サービスを起動するとpslist / pskillが利用できるようになります。

サーバで使うゴールドディスクって

何よ、それ?という人が多いと思います。これは私が外資系金融機関で勤務していた時に勤務先が採用していた方式でシステムをリリースする際にOS領域のバックアップを取るのにNorton Ghost等のソフトウェア方式では時間が掛かるため時間短縮のためにとっていた方式です。これでシステム飛びましたとか出来ないやんけーとかのクレームは冗談抜きで受け付けません、自己責任でお願いします。

ついでにいうとメーカーにこの話をしても良い顔されません。確実に苦虫潰した反応されます。理由は簡単で同じ容量のHDDでもメーカーが異なると容量が合わないというエラーになって出来ない場合があるからです。

(要するに体験したことがあるのです)

前提としてサーバに刺さっているHDDにOSを入れていることが前提ですがSSDもできるはずです。Raidは1か0+1のみで5や6、JBODは対象外です。また、更新されるデータが入っている場合はそのデータがバックアップから戻せることが前提です。OSについてはWindows/Linuxどちらもいけますが、Active DirectoryドメインコントローラはサーバのSIDチェックがあるのでこの方式でバックアップしたものを差しても、他のドメコンから拒否されて隔離されますので出来ません。

やり方は簡単です。バックアップ時はOSを落とす、HDDを抜く、電源を上げる、HDD差してリビルドする、です。なお、順番を間違えて先にHDDを差して電源を入れた場合データは保証できません。

バックアップを戻すときは、電源を落とす、Raid1で2本+hotspareなら三本とも抜く(わからなくならないように注意)、バックアップをHDDを差す、電源入れて問題がなければ抜いたRaid1ディスク一本とホットスペアを差す、です。

なお、バックアップから戻したときにサーバのドメイン認証が出来ない場合があるのでその場合はドメイン再参加しましょう。

このバックアップの良いところはWindowsupdateでおかしな挙動を示すと困る場合にサーバのOS落としてディスクを抜いてバックアップ、電源入れてUpdateする、問題なければディスクを差すという対応が可能な一方で電源を落としたことでマザー故障で起動しない場合が希にあるので5年以上稼働するサーバではお薦めできません。またこのゴールドディスクを作成するタイミングを変更することで仮想OSのテンプレートのように使い回すことも可能です。

そういうことで金融機関では同じ型番の機種で統一することで、メモリやCPU追加、上記のような作業でマザー故障した場合に、同じ型番のサーバに交換して即時リカバリ出来るようにしていました。仮想が進んだ今、やってるかどうかは知りません。

VDIのvSphere Client(Web込)インベントリ削除は注意が必要

非常にお久しぶりな更新です。

View5.xから6.2.3にアップデート作業のひとつにvShield EndPoint製品のアップデートがありました。これをアップデートした瞬間に発生したトラブルのひとつにvDSの接続に関するテーブルのデータ不整合があります。
この症状により発生した症状として
①起動したままのVDIが接続できない。
 →シャットダウンして電源ONで回復
②シャットダウンして電源ONで回復しなかったもの
 →vNIC付け直し
③vSphere Clientで電源が入らなくなったVDI
 →vSphere Clientのインベントリから削除

で、対応しています。が!『vSphere Clientのインベントリから削除』を行う際に
Connection serverのプールからVDI登録を削除せずに『インベントリから削除』を行うとConnection ServerのLDAPにもvCenterDBにもどこにも登録情報が見当たらない状態になります。(特にフルクローンの流動プール)

その場合VMXファイルの読み込みで戻した後にvmxファイルのmachine.idの値をNULL化->VDI起動->プールに登録という操作が必要になります。

なお、この件はvCenter4でサポート外のWindows2012を起動するためにUEFI BIOSファイルに関する記述を追加したことがある私もさすがに最後までこの値が原因と思っていなかったので最後までここに原因があると思っていませんでした。

6.2.3へのアップグレードに関しては別途報告します。

今のお仕事

本職で色々とありまして自分の時間が作れずにいます。

状況ですがVDIは構築中のFlexPod(Cisco UCS/NetApp FAS8000系)のUCSがランダムReadが問題のないESXと比較して原因不明の半分程度低速しか出ず、NFSマウントなのでネゴシエーションかとおもいきやESX再起動でも治らずにいます。またDRSのプロセスが不定期定期に跳ね上がるため、VMwareのサポセンに問い合わせるもCiscoがcompatibilityリストの申請漏れでVMwareのサポートを受けられず、その交渉を依頼しつつESXのOS領域がRaid1なのでシャットダウンしてディスク1本抜いてOSを新規ISOイメージで入れ直してみるかどうかを検討しています。

クラウドサービス上でサービスを展開する業者さんとの接続で現在利用中のプロバイダがサービス展開予定があるので前倒しで対応するということから始まり別担当が対応していたので当初静観していたのですが話がまとまらず、なぜかプロバイダと業者の打ち合わせに参加し業者を説得&なぜ顧客の立場の自分がプロバイダと業者間の概要設計を行っているか意味が分からない状態です。

 

 

閑話休題

 
WindowsXP自体に作成したプッシュ型のプログラム配信VBScriptWindows7対応とプログラム自体が5年前に書いたものなので、今見ると非常に下手な仕上がりなので再作成をしています。このため、数日間は更新ができない見込みです。

さて、その間をつなぐ為に1つスクリプトを投下したいと思います。
つい最近までLANScopeを利用していたのですが、そちらからPC監視ソフトをSkySeaに乗り換えています。これは自社の問題が大いに絡むのですが、システム部門のサポートメンバがサポートしやすいようにするためにアカウントの切り替えを行わずに自分のアカウントにDomain Adminをつけてしまっているため、LANScopeを利用していた頃はログインスクリプトインストーラを叩く仕組みになっていたため、インスト&再起動をしないと反映されない監視プログラムをインストしたまま放置せざるを得ない状態になることがありました。

このため、フルクローンを利用している環境とパソコンのある環境でほぼメンテナンスフリーでインストールを行ってくれるスクリプトを作成しました。処理判定としては以下のとおりです。
①サーバOSでのインストールを行わない。
②クライアントOSの32bit/64bitの判定
③SkySea構築段階でLANScopeからの切り替えを前提とした
 『監視状態(負荷がかかる)』と『非監視』を作成し、切り替え期日前であれば
 『非監視』に、切り替え後は『監視状態』のツリーに配置されるようにする
④PC名やIPをベースに仮想PCかパソコンかを判定、さらにホスト名から個人割り当てのPC(接頭語+社員番号6桁以上)か共有PCかを判定する
⑤④の結果を元にインストーラをコピーしインストールをするが、その際にSkySeaの監視ツリーに該当しないPC(パソコンやADのアカウントがないのに作成された個人PC等)にインストールされた場合は、アラートメールを送信する。
※メール送信先メールサーバはシステム用のメールサーバの為、セキュリティレベルは下げています。

といった内容のものになっています。

 

'▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△
'△
'▼ 作成日時:2016/3/8
'△ スクリプト機能:SkySea配布スクリプト
'▼ 作成目的:LanScopeからSkySeaへの切替を想定
'△ 機能概要:SkySeaがインストールされている環境に
'▼      LanScope/SkySea共にインストールを実行しない
'△      Windowsが32bitか64bitか判定する
'▼      SkySeaのインストーラがない場合はコピーする。
'△
'▼      
'△
'▼
'△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△▼△

on error resume next

Set FSO = CreateObject("Scripting.FileSystemObject")
Set objShell = Wscript.CreateObject("Wscript.Shell")
Set objDic_Seg = CreateObject("Scripting.Dictionary")
Set obj_SkySea_Dev = CreateObject("Scripting.Dictionary")
Set objDic_SkySeaInst_File = CreateObject("Scripting.Dictionary")
Set Cdo = WScript.CreateObject("CDO.Message")

'◆スクリプト実行日付(テスト向け)
Exec_date = date()
'Exec_date = cdate("2016/3/31")


'◆LANSCOPEからSkySeaに切り替える日
Migration_date = cdate("2016/3/27")

'チェックするアプリ名
'LANSCOPE部は何も考えずに消せるように...
Str_LANScopeName = "LanScope Cat MR"
Str_Exec_dir_path = "c:system_admin"

'配布モードのインストーラディレクト
Str_LANSCOPEinst_Dir ="【Domain Controller】 etlogon"
Str_LANSCOPEinst_File = "mrinst.exe"

'LANScopeのアンインストーラ
Str_LANSCOPE_Uninst_File = "LANSCOPE_Uninstall.exe"

'あえて分けて変数化
'SkySea監視モードディレクト
Str_SkySeaProd_Dir="【SkySeaServer】prod$"
Str_SkySeaNoMonitor_Dir="【SkySeaServer】 est$"

'対象ドメイン
Str_Domain = "【HogeHoge.local】"
Domain_DSN = "dc=" & replace(Str_Domain, "." , ",dc=")

'どのインストーラを利用するかのフラグ値
Flg_PC_Department = "unAssigned" '初期値は所属未定を利用

'SkySeaインストーラ
objDic_SkySeaInst_File.add "32", "SKYSEADivSetup.exe"
objDic_SkySeaInst_File.add "64", "SKYSEADivSetup64.exe"

'SkySea_所属名
obj_SkySea_Dev.add "VDI_【GCompany】P", "【GCompany】本部系-【GCompany】【child CompB】-仮想PC(View)"
obj_SkySea_Dev.add "VDI_Di", "【GCompany】本部系-【グループ会社名】-【child CompA】仮想PC(View)"
obj_SkySea_Dev.add "VDI_Share_Di", "【GCompany】本部系-【グループ会社名】-【child CompA】拠点仮想PC(View)"
obj_SkySea_Dev.add "VDI_【GCompany】", "【GCompany】本部系-【グループ会社名】-仮想PC(View)"
obj_SkySea_Dev.add "VDI_DW", "【GCompany】本部系-【child CompC】【child CompF】-仮想PC(View)"
obj_SkySea_Dev.add "VDI_【child compD】", "【GCompany】本部系-【child CompD】-仮想PC(View)"
obj_SkySea_Dev.add "VDI_Ace", "【GCompany】本部系-【GCompany】【child CompE】-仮想PC(View)"
obj_SkySea_Dev.add "FAT_Di", "【child CompA】-FATPC"
obj_SkySea_Dev.add "unAssigned", "所属未定"
obj_SkySea_Dev.add "Manager", "管理機初期登録"

 


'Log Strings
Str_logs =""


'◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆
'◇FATか仮想PC(【GCompany】/Di/【GCompany】P/【child CompD】)か判定出来るようにする
'◆データセンタはDCと表記、仮想PCはVDIという表記でスクリプト内で
'◇処理判定を行う 
'◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆

'社員番号桁数定義
Int_Employee_Digits = 6

'◆メール送信設定
strFrom = "<SkySeaAgent@ドメイン>"
'strReply = "<>"

strServer = "サーバIP"
nPort = 25
'strUser = ""
'strPass = "<smtpサーバのパスワード>"
strTo = "<>"
strCc = ""
strBcc = ""
'以下のメールのタイトルと本文では『対象端末:』と##CRLF##をスクリプト内でそれぞれ置き換える
strSubject = "【SkySeaインストール】所属未定にPCが登録されました。対象端末:"
strTextbody = "SkySeaエージェントをインストールしましたが所属未定に登録されました。##CRLF##対象端末:"

 


'共有PCの接頭語、修飾語(小文字表記するのでホスト名の小文字変換をする
Arry_VDI_Prefix = Array ("【GCompany】pshare","vishare","viblock", "viarea")

'◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆

 


'※※※※※※※※※※※※※※※※※※※※※※※※※※
'初期動作確認
'※※※※※※※※※※※※※※※※※※※※※※※※※※


'ホスト名を取得
str_HostName     = Func_Get_Hostname()
'IPを取得
Str_HostIPaddrss = Func_Get_IP()


'OSビット数判定。戻り値が0の場合はサーバOSの為スクリプト自体終了
Int_OS_Bit = Func_OSbit_chk()
if Int_OS_Bit  = 0 then
 objShell.LogEvent 0,"SkySeaインストーラ"& VBCrLF &"OSがサーバのため実行キャンセルします。",str_HostName
 wscript.quit
end if

'ダウンロードして実行するためのフォルダのチェックと作成
if FSO.folderExists(Str_Exec_dir_path) = false then
 FSO.createFolder(Str_Exec_dir_path)
 Str_logs = Str_logs  & "初期動作確認:インストーラのコピー先がないため作成します。" & vbcrlf
end if

Str_logs = Str_logs  & vbcrlf & "◆◇◆◇◆◇【初期動作確認開始】◆◇◆◇◆◇" & vbcrlf & vbcrlf
Str_logs = Str_logs  & "Flg_PC_Department: " & Flg_PC_Department & vbcrlf
Str_logs = Str_logs  & "obj_SkySea_Dev(Flg_PC_Department): " & obj_SkySea_Dev(Flg_PC_Department) & vbcrlf


'監視ソフト(LANSCOPE/SkySeaインストールチェック)
Flg_MonitorSoft_Status =  Func_MonitorSoft_Check()

 

Select case Flg_MonitorSoft_Status
 Case 6 'LANScope/SkySea共にインスト済:6は何もしない
  Str_logs = Str_logs  & "初期処理中:Func_MonitorSoft_Check()が" &  Flg_MonitorSoft_Status & "を返しました" & vbcrlf _
             & "LANSCOPEとSkySeaが共存しています。LANScope使用終了期間判定後、期日後であればアンインストを行います。"
     if datediff("d",Exec_date, Migration_date ) < 0 then
      'Migration_dateより後の日付
   'LANSCOPEはアンインストする
   Str_logs = Str_logs & "本日日付: "& Exec_date & " 移行日付: " & Migration_date &" LANSCOPEの使用終了後と判定されたためアンインストします" &vbcrlf
   call Sub_LanScope_Uninst()
   Str_logs = Str_logs  & "初期処理中:SkySeaがインストされている為終了します" & vbcrlf
  else
   Str_logs = Str_logs  & "初期処理中:SkySeaがインストされている為終了します" & vbcrlf
  end if
  
 case 4 'SkySeaのみインスト済:4 はLANSCOPEは入れない
  Str_logs = Str_logs  & "初期処理中:Func_MonitorSoft_Check()が" &  Flg_MonitorSoft_Status & "を返しました。SkySeaのみインストールされている状態です" & vbcrlf
   Str_logs = Str_logs  & "初期処理中:SkySeaがインストされている為終了します" & vbcrlf
'wsh.echo "##Flg_MonitorSoft_Status: " & Flg_MonitorSoft_Status

 Case 2 'LANScopeのみインスト済:2は配布モードのSkySeaをダウンロードしてインスト
  Str_logs = Str_logs  & "初期処理中:Func_MonitorSoft_Check()が" &  Flg_MonitorSoft_Status & "を返しました" & vbcrlf _
             & "LANScopeのみインストールされている状態のため、LANSCOPEの使用終了判定後、期日後であればアンインスト後にSkySeaをインストします" &vbcrlf

     'SkySeaのインストーラを決定
  call Sub_SkySea_Installer_judgement()
  if isnull(obj_SkySea_Dev(Flg_PC_Department) ) = true then
   Str_SkySea_Dev = obj_SkySea_Dev("unAssigned")
  else
   Str_SkySea_Dev = obj_SkySea_Dev(Flg_PC_Department)
  end if

  'Migration_dateより後の日付の場合LANScopeアンインストする
     if datediff("d",Exec_date, Migration_date ) < 0 then
  Str_logs = Str_logs & "本日日付: "& Exec_date & " 移行日付: " & Migration_date &" LANSCOPEの使用終了後と判定されたため、アンインスト後にSkySeaをインストします" &vbcrlf
      call Sub_LanScope_Uninst()
   'SkySeaインストーラパスを生成
   Str_SkySea_Installer = Str_SkySeaProd_Dir & "" & Str_SkySea_Dev  & "" & objDic_SkySeaInst_File(Cstr(Int_OS_Bit))
     else
   'SkySeaインストーラパスを生成
   Str_logs = Str_logs & "本日日付: "& Exec_date & " 移行日付: " & Migration_date &" LANSCOPEの使用終了前と判定されたため、非監視モードのSkySeaをインストします" &vbcrlf
   Str_SkySea_Installer = Str_SkySeaNoMonitor_Dir & "" & Str_SkySea_Dev  & "" & objDic_SkySeaInst_File(Cstr(Int_OS_Bit))
     end if

'wsh.echo "[プロセス2]:Flg_PC_Department" & Flg_PC_Department
  Str_localSkySea_installer = Str_Exec_dir_path & "" & objDic_SkySeaInst_File(Cstr(Int_OS_Bit))
  Str_logs = Str_logs  & "初期処理中:SkySeaインストパスを生成しました" & vbcrlf
  Str_logs = Str_logs  & "初期処理中:パス> " & Str_SkySea_Installer & vbcrlf & vbtab & Str_localSkySea_installer
'wsh.echo "Flg_MonitorSoft_Status: " & Flg_MonitorSoft_Status
  

 Case 0 'LANScope/SkySea共に未インスト:1は監視モードのSkySeaをインスト
  Str_logs = Str_logs  & "初期処理中:Func_MonitorSoft_Check()が" &  Flg_MonitorSoft_Status & "を返しました" & vbcrlf _
             & "何もインストされていないため、SkySeaを監視モードでインストします。" & vbcrlf

  call Sub_SkySea_Installer_judgement()
  if isnull(obj_SkySea_Dev(Flg_PC_Department) ) = true then
   Str_SkySea_Dev = obj_SkySea_Dev("unAssigned")
  else
   Str_SkySea_Dev = obj_SkySea_Dev(Flg_PC_Department)
  end if
  'SkySeaインストーラパスを生成
'wsh.echo "[プロセス0]:Flg_PC_Department: " & Flg_PC_Department
  'ダウンロード元のパス生成
  Str_SkySea_Installer = Str_SkySeaProd_Dir & "" & Str_SkySea_Dev  & "" & objDic_SkySeaInst_File(Cstr(Int_OS_Bit))
  'ダウンロード先にファイルがない場合はunSAssignedでパス再生成
  If FSO.FileExists(Str_SkySea_Installer) = false then Str_SkySea_Installer = Str_SkySeaProd_Dir & "" & obj_SkySea_Dev("unAssigned")  & "" & objDic_SkySeaInst_File(Cstr(Int_OS_Bit))
  Str_localSkySea_installer = Str_Exec_dir_path & "" & objDic_SkySeaInst_File(Cstr(Int_OS_Bit))
  Str_logs = Str_logs  & "初期処理中:SkySeaインストパスを生成しました" & vbcrlf
  Str_logs = Str_logs  & "初期処理中:パス> " & Str_SkySea_Installer & vbcrlf & vbtab & Str_localSkySea_installer
'wsh.echo "Flg_MonitorSoft_Status: " & Flg_MonitorSoft_Status

 
End select

'wsh.echo "Flg_MonitorSoft_Status: " & Flg_MonitorSoft_Status
'wsh.echo "###Str_SkySea_Installer: " & Str_SkySea_Installer
'wsh.echo "###Str_localSkySea_installer: " & Str_localSkySea_installer


'Flg_MonitorSoft_Statusが4未満なら継続
if Flg_MonitorSoft_Status >=4 then

elseif Flg_MonitorSoft_Status < 4 then
 Str_logs = Str_logs  & "SkySeaのインストールを開始します" & vbcrlf
 Flg_inst_Status = Func_SkySea_Inst()
 '2016/4/1以降に所属未定になった場合はメール送信
 if Flg_PC_Department = "unAssigned" and datediff("d",Exec_date, Migration_date ) < 0 then call Sub_SendMail_unAssignedGroup()
end if
'wsh.echo "◆◇ログの確認"& vbcrlf & Str_logs

'イベントログ出力
objShell.LogEvent 4, "[SkySeaインストールスクリプト:SkySeaInstall.vbs実行結果]" & vbcrlf & vbcrlf & Str_logs


'===================================================
Sub Sub_SendMail_unAssignedGroup()

 '送信メール生成

 '以下のメールのタイトルと本文では『対象端末:』と##CRLF##をスクリプト内でそれぞれ置き換える
 strSubject = replace("【SkySeaインストール】所属未定にPCが登録されました。対象端末:", "対象端末:" ,"対象端末:" & str_HostName)
 strTextbody = replace("SkySeaエージェントをインストールしましたが所属未定に登録されました。##CRLF##対象端末:", "##CRLF##対象端末:" ,vbcrlf & crlf & "対象端末:" & str_HostName & " IP: " & Str_HostIPaddrss)
' strTextbody = replace("SkySeaエージェントをインストールしましたが所属未定に登録されました。##CRLF##対象端末:", "##CRLF##" ,vbcrlf & vbcrlf)

  Cdo.From = strFrom
 ' Cdo.ReplyTo = strReply
  Cdo.To = strTo
 ' Cdo.Cc = strCc
 ' Cdo.Bcc = strBcc
  Cdo.Subject = strSubject
  Cdo.Textbody = strTextbody
 ' Cdo.AddAttachment strAddAttachment

  Cdo.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2
  Cdo.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = strServer
  Cdo.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = nPort
  Cdo.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpconnectiontimeout") = 30
 ' Cdo.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = true
 ' Cdo.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = true
 ' Cdo.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") = strUser
 ' Cdo.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = strPass

  Cdo.Configuration.Fields.Update

  on error resume next
  Cdo.Send

End Sub

sub Sub_LanScope_Uninst()

 Flg_LanScope_Uninst = 0

 cnt = 1
 do Until cnt > 10

  If FSO.FileExists(Str_LANSCOPEinst_Dir & "" & Str_LANSCOPE_Uninst_File) = true then
   if FSO.FileExists(Str_Exec_dir_path & "" & Str_LANSCOPE_Uninst_File) = true then FSO.DeleteFile Str_Exec_dir_path & "" & Str_LANSCOPE_Uninst_File
    FSO.CopyFile Str_LANSCOPEinst_Dir & "" & Str_LANSCOPE_Uninst_File, Str_Exec_dir_path & "" & Str_LANSCOPE_Uninst_File, true
  end if
  if FSO.FileExists(Str_Exec_dir_path & "" & Str_LANSCOPE_Uninst_File) = true then
   Str_logs = Str_logs  & "Sub_LanScope_Uninst()でアンインストーラコピー実行。実行結果: 成功" & VBcrlf
   Flg_LanScope_Uninst = 1
   exit do
  else
   Str_logs = Str_logs  & "Sub_LanScope_Uninst()でアンインストーラコピー実行。実行結果: 失敗" & VBcrlf
   'サーバの負荷が下がるのを15-90秒待つ
   call Func_Wait_timer()
   
   '10回トライしてダメだったらログに出す
   if cnt = 10 then
    Str_logs = Str_logs  & "Sub_LanScope_Uninst()でアンインストーラコピー実行。実行結果: 10回失敗したので諦める" & VBcrlf
    Flg_LanScope_Uninst = 2
    Exit sub
   end if
  end if
  cnt = cnt+ 1
 loop

 'ダウンロードに成功したのでインストールを実行
 if Flg_LanScope_Uninst = 1 then
  Str_Cmd =  Str_Exec_dir_path & "" & Str_LANSCOPE_Uninst_File
  Set objExec = objShell.Exec(Str_Cmd)

  '最大5分間チェック
  cnt = 0
  For cnt = 0 to 300
   'アンインスト完了時にはFunc_LANScope_Existing_chkが0を返す
   if Func_LANScope_Existing_chk() = 0 then
    'Str_logs = Str_logs  & "Sub_LanScope_Uninst()でアンインストーラ実行。実行結果:成功" & VBcrlf
    Flg_LanScope_Uninst = 1
    FSO.DeleteFile  Str_Exec_dir_path & "" & Str_LANSCOPE_Uninst_File
    exit for
   else
    if cnt = 300 then Flg_LanScope_Uninst = 3
    wscript.sleep 1000
   end if
  next
  '5分待ちでだめだった場合は、ログを出す
  if Flg_LanScope_Uninst =3 then Str_logs = Str_logs  & "Sub_LanScope_Uninst()でアンインストーラ実行。実行結果:5分待ったが反映せず" & VBcrlf
  'アンインスト成功
  if Flg_LanScope_Uninst =1 then Str_logs = Str_logs  & "Sub_LanScope_Uninst()でアンインストーラ実行。実行結果:成功" & VBcrlf

 end if


End sub


Function Func_SkySea_Inst()

'wsh.echo "Str_SkySea_Installer: " & Str_SkySea_Installer
'wsh.echo "Str_localSkySea_installer: " & Str_localSkySea_installer


'wsh.echo "◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇"
'wsh.echo "Func_SkySea_Inst"
'wsh.echo "◆◇◆◇◆◇◆◇◆◇◆◇◆◇◆◇"

 Func_SkySea_Inst = 0

 cnt = 0
 if FSO.FileExists( Str_localSkySea_installer) = true then FSO.DeleteFile Str_localSkySea_installer

 do Until cnt > 10
'wsh.echo "Do内:" & cnt
'wsh.echo "Str_localSkySea_installer: " & Str_localSkySea_installer
'wsh.echo "Str_SkySea_Installer: " & Str_SkySea_Installer
  If FSO.FileExists(Str_SkySea_Installer) = true then
   FSO.CopyFile Str_SkySea_Installer, Str_localSkySea_installer, true
   if FSO.FileExists(Str_localSkySea_installer) = false then
    Str_logs = Str_logs  & "Func_SkySea_Inst()でインストーラコピー実行。実行結果: 失敗" & VBcrlf
    'サーバの負荷が下がるのを15-90秒待つ
    call Func_Wait_timer()
    
    '10回トライしてダメだったらログに出す
    if cnt = 10 then
     Str_logs = Str_logs  & "Func_SkySea_Inst()でインストーラコピー実行。実行結果: 10回失敗したので諦める" & VBcrlf
     Func_SkySea_Inst = 2
     Exit Function
    end if
   else
    Str_logs = Str_logs  & "Func_SkySea_Inst()でインストーラコピー実行。実行結果: 成功" & VBcrlf
    
    Func_SkySea_Inst = 1
    exit do
   end if
  end if
  cnt = cnt + 1
 loop

 'ダウンロードに成功したのでインストールを実行
 if Func_SkySea_Inst = 1 then
'wsh.echo "###SkySea DownLoad成功###"
  Str_Cmd = Str_localSkySea_installer & " /qn"
'  objShell.run = Str_Cmd
  Set oExec = objShell.Exec(Str_Cmd)
  
  '最大5分間チェック
  cnt = 0
  For cnt = 0 to 300
   'インスト完了時にはFunc_SkySea_Existing_chkが2を返す
   if Func_SkySea_Existing_chk() = 4 then
    Str_logs = Str_logs  & "Func_SkySea_Inst()でインストーラ実行。実行結果:成功" & VBcrlf
    Func_SkySea_Inst = 1
    FSO.DeleteFile  Str_localSkySea_installer
    exit for
   else
    if cnt = 300 then Func_SkySea_Inst = 3
    wscript.sleep 1000
   end if
  next
  '5分待ちでだめだった場合は、ログを出す
  if Func_SkySea_Inst =3 then Str_logs = Str_logs  & "Func_SkySea_Inst()でインストーラ実行。実行結果:5分待ったが反映せず" & VBcrlf
  if Func_SkySea_Inst =1 then Str_logs = Str_logs  & "Func_SkySea_Inst()でインストーラ実行。実行結果:完了" & VBcrlf
 end if

End Function

Sub Sub_Chk_employee_No(int_Emp)

 Str_logs = Str_logs  & "Sub_Chk_employee_No()で社員番号:" & int_Emp & "を受け取りました" & VBcrlf


  Const ADS_SCOPE_SUBTREE = 2

 Set objConnection = CreateObject("ADODB.Connection")
 Set objCommand =   CreateObject("ADODB.Command")
 objConnection.Provider = "AD【GCompany】SOObject"
 objConnection.Open "Active Directory Provider"
 
 Set objCOmmand.ActiveConnection = objConnection
 objCommand.CommandText = _
     "Select Name,distinguishedName from 'LDAP://"& Domain_DSN & "' " _
         & "Where objectClass='user' and sAMAccountName='" & int_Emp & "'" 


 objCommand.Properties("Page Size") = 1000
 objCommand.Properties("Searchscope") = ADS_SCOPE_SUBTREE

 Set objRecordSet = objCommand.Execute

 if err.number = 0 and objRecordSet.RecordCount > 0 then
   Str_logs = Str_logs  & "Sub_Chk_employee_No()でセキュリティグループ情報を取得開始" & VBcrlf
  Str_logs = Str_logs  & "Sub_Chk_employee_No()でADの登録を確認" & VBcrlf
  tmp_Dev =  objRecordset.Fields("distinguishedName")
  if instr(tmp_Dev, "【child CompA】") > 0 then
   Str_logs = Str_logs  & "Sub_Chk_employee_No()で【child CompA】と判定" & VBcrlf
   Flg_PC_Department = Flg_PC_Department & "Di"
  elseif instr(tmp_Dev, "【child CompD】") > 0 then
   Str_logs = Str_logs  & "Sub_Chk_employee_No()で【child CompD】と判定" & VBcrlf
   Flg_PC_Department = Flg_PC_Department & "Seikodo"
  elseif instr(tmp_Dev, "【GCompany】【child CompB】") > 0 then
   Str_logs = Str_logs  & "Sub_Chk_employee_No()で【child CompB】と判定" & VBcrlf
   Flg_PC_Department = Flg_PC_Department & "【GCompany】P"
  elseif instr(tmp_Dev, "【child CompC】") > 0 then
   Str_logs = Str_logs  & "Sub_Chk_employee_No()でDWと判定" & VBcrlf
   Flg_PC_Department = Flg_PC_Department & "DW"
  elseif instr(tmp_Dev, "【GCompany】【child CompE】") > 0 then
   Flg_PC_Department = Flg_PC_Department & "VDI_Ace"
  else
   Str_logs = Str_logs  & "Sub_Chk_employee_No()で【GCompany】と判定" & VBcrlf
   Flg_PC_Department = Flg_PC_Department & "【GCompany】"
  end if

 else
  Str_logs = Str_logs  & "Sub_Chk_employee_No()でADの登録が見つからないため『所属未定』として処理継続します。"  & VBcrlf
  Flg_PC_Department = "unAssigned"
 end if

end sub

Sub Sub_SkySea_Installer_judgement()

 Str_logs = Str_logs  & "PC種別判断のためSub_SkySea_Installer_judgement()が実行されました。"  & VBcrlf


 'SkySeaで利用するインストーラが仮想用かを判定する。
 '判定はLDAPドメイン不参加PCを振り落す
 '接頭語とセグメントで判断でセグメントから実行
 
 'まずはVDIかそれ以外(所属未定を利用)を判定
 if Func_Chk_VDI_FATPC() = 1 then
  Str_logs = Str_logs  & "Func_Chk_VDI_FATPC() の戻り値として1が返されました。Flg_PC_Department に'VDI_'が入ります"   & VBcrlf
  Flg_PC_Department = "VDI_" 'VDIは1になる

  'PC名がXX社員番号(Vi123456)になっているか
  '2016年時点では6ケタだが、それ以上になった場合も想定する
  if isNumeric(right(str_HostName, 6) ) = true then
   Str_logs = Str_logs  & "◆Sub_SkySea_Installer_judgement()で個人PCと判断"  & VBcrlf
   '社員番号からLDAPで検索し、SkySeaの所属を決める
   call Sub_Chk_employee_No( right(str_HostName, 6) )
   
   
  '7ケタ以上になった場合に実行
  elseif Int_Employee_Digits > 6 and isNumeric(right(str_HostName, Int_Employee_Digits) ) = true then
   '個人PCと判断しLDAPで社員番号を検索し、所属を確認
   Str_logs = Str_logs  & "Sub_SkySea_Installer_judgement()で7ケタ以上の社員番号の個人PCと判断"  & VBcrlf
   call Sub_Chk_employee_No( right(str_HostName, Int_Employee_Digits) )
  else
   '共有PCと判断
   Str_logs = Str_logs  & "Sub_SkySea_Installer_judgement()で共有PCと判断"  & VBcrlf
   Flg_PC_Department = Flg_PC_Department &  "Share_"
   'まずはネーミングルールで【GCompany】共有か【child CompB】共有かを判断
   for x = 0 to Ubound(Arry_VDI_Prefix)
    '共有PCの接頭語、修飾語(小文字表記するのでホスト名の小文字変換をする
    'Arry_VDI_Prefix = Array ("【GCompany】pshare","vishare","viblock", "viarea")
    if instr(Lcase(str_HostName),Lcase(Arry_VDI_Prefix(x)) ) > 0 then
     select case x
      case 0 '【GCompany】P共有
       Flg_PC_Department = Flg_PC_Department & "【GCompany】P"
       Str_logs = Str_logs  & "Sub_SkySea_Installer_judgement()で【child CompB】共有と判断"  & VBcrlf
       exit for
      case 1 '【GCompany】共有
       '【GCompany】は統一なので"_Share"を消してから足す
       Flg_PC_Department = replace(Flg_PC_Department, "_Share", "" ) & "【GCompany】"
       Str_logs = Str_logs  & "Sub_SkySea_Installer_judgement()で【GCompany】共有と判断" & VBcrlf
       exit for
      case 2,3 'Di共有
       Flg_PC_Department = Flg_PC_Department & "Di"
       Str_logs = Str_logs  & "Sub_SkySea_Installer_judgement()でDi共有と判断" & VBcrlf
       exit for
      case else
       Flg_PC_Department = "unAssigned"
       Str_logs = Str_logs  & "Sub_SkySea_Installer_judgement()で共有PC命名規則と不一致のため所属未定として処理します" & VBcrlf
       exit for
     end select
    end if
   next
  end if
 else
  Str_logs = Str_logs  & "Func_Chk_VDI_FATPC() の戻り値として1以外が返されました"   & VBcrlf
 end if


End sub


Function Func_Chk_VDI_FATPC()

'初期値0はFAT(所属未定に入れるEXEを利用)、1は仮想
Func_Chk_VDI_FATPC = 0

 '仮想PCかノーマルPCかを判定する
 'VDIは『VMware View Agent』『VMware Tools』がインストされているので
 'どちらかにヒットしたらVDI


 Const HKEY_LOCAL_MACHINE = &H80000002

 strComputer = "."
 Set objRegProv = GetObject("winmgmts:{impersonationLevel=impersonate}!" & strComputer & " ootdefault:StdRegProv")

 sytKey = "SOFTWAREMicrosoftWindowsCurrentVersionUninstall"
 Call objRegProv.EnumKey(HKEY_LOCAL_MACHINE, sytKey, ccSubKeys)

 For each strSubKey in ccSubKeys

   dwVal_strParentKeyName = objRegProv.GetStringValue(HKEY_LOCAL_MACHINE, sytKey & "" & strSubKey, "ParentKeyName", strParentKeyName)
   If dwVal_strParentKeyName <> 0 Then ' ParentKeyNameが無いものが対象(更新インストールではないもの)

     dwVal_dwSystemComponent = objRegProv.GetDWORDValue(HKEY_LOCAL_MACHINE, sytKey & "" & strSubKey, "SystemComponent", dwSystemComponent)
     If dwVal_dwSystemComponent <> 0 Or dwSystemComponent = 0 Then ' システムフラグが無いまたはゼロのものが対象

       dwVal_strDisplayName = objRegProv.GetStringValue(HKEY_LOCAL_MACHINE, sytKey & "" & strSubKey, "DisplayName", strDisplayName)
       If dwVal_strDisplayName = 0 And strDisplayName <> "" Then ' 表示名があるものが対象
        'VDIはFunc_Chk_VDI_FATPCを1に
   if instr(strDisplayName, "VMware View Agent") > 0 or  instr(strDisplayName, "VMware Tools") > 0 then
    Func_Chk_VDI_FATPC =1
    Str_logs = Str_logs  & "Func_Chk_VDI_FATPC()で仮想PCと判断" & VBcrlf
    exit for
   end if
       End If
     End If
   End If
 Next

 if Func_Chk_VDI_FATPC = 0 then Str_logs = Str_logs  & "Func_Chk_VDI_FATPC()でFATと判断" & VBcrlf

end function

Function Func_LANScope_Inst()

 Func_LANScope_Inst = 0

 'インストーラの容量が小さいのでAD03のを利用する
 cnt = 1
 do Until cnt > 10
  If FSO.FileExists(Str_LANSCOPEinst_Dir & "" & Str_LANSCOPEinst_File) = true then
   FSO.CopyFile Str_LANSCOPEinst_Dir & "" & Str_LANSCOPEinst_File, Str_Exec_dir_path, true
  end if
  if Error.Number <>0 then
   Str_logs = Str_logs  & "Func_LANScope_Inst()でインストーラコピー実行。実行結果: 失敗" & VBcrlf
   'サーバの負荷が下がるのを15-90秒待つ
   call Func_Wait_timer()
   
   '10回トライしてダメだったらログに出してLANSCOPEは入れない(どうせ近いうちに停止するので)
   Func_LANScope_Inst = 2
   Str_logs = Str_logs  & "Func_LANScope_Inst()でインストーラコピー実行。実行結果: 10回失敗したので諦める" & VBcrlf
   Exit Function
  else
   Str_logs = Str_logs  & "Func_LANScope_Inst()でインストーラコピー実行。実行結果: 成功" & VBcrlf
   Func_LANScope_Inst = 1
   exit do
  end if
 loop

 'ダウンロードに成功したのでインストールを実行
 if Func_LANScope_Inst = 1 then
  Str_Cmd = Str_Exec_dir_path & "" & Str_LANSCOPEinst_File & " /qn"
  objShell.run = Str_Cmd
  
  'LANSCOPEは15秒程度でインストできるので最大5分間チェック
  cnt = 0
  For cnt = 0 to 300
   'インスト完了時にはFunc_LANScope_Existing_chkが2を返す
   if Func_LANScope_Existing_chk() = 2 then
    Str_logs = Str_logs  & "Func_LANScope_Inst()でインストーラ実行。実行結果:成功" & VBcrlf
    Func_LANScope_Inst = 3
    FSO.DeleteFile Str_Exec_dir_path & "" & Str_LANSCOPEinst_File
    exit for
   else
    wscript.sleep 1000
   end if
  next
  '5分待ちでだめだった場合は、所詮LANSCOPEなのでログだけ出してフォローせず。
  if Func_LANScope_Inst = 1 then Str_logs = Str_logs  & "Func_LANScope_Inst()でインストーラ実行。実行結果:5分待ったが反映せず" & VBcrlf
 end if

End Function

Function Func_MonitorSoft_Check()
'監視ソフト(LANSCOPE/SkySeaインストールチェック)
 '◆フラグ値について
 '未チェック:0
 'LANScope/SkySea共に未インスト:1
 'LANScopeのみインスト:2
 'SkySeaのみインスト:4
 'LANScope/SkySea共にインスト:6

 '初期値は0
 Func_MonitorSoft_Check=0
 'LANSCopeをチェック
 'ただし64bitOS利用でLANSCOPEが入っているPCは
 'ユーザは利用していないので判定しない。
 Func_MonitorSoft_Check = Func_LANScope_Existing_chk()

'wsh.echo "Func_MonitorSoft_Check【前】 : " & Func_MonitorSoft_Check
 'SkySeaをレジストリでチェック
 Func_MonitorSoft_Check = Func_MonitorSoft_Check + Func_SkySea_Existing_chk()

wsh.echo "Func_MonitorSoft_Check: "& Func_MonitorSoft_Check
 
 Str_logs = Str_logs  & "Func_MonitorSoft_Check()が実行されました。実行結果: " & Func_MonitorSoft_Check & vbcrlf


end Function

'----------------------------------------

Function Func_SkySea_Existing_chk()

 Func_SkySea_Existing_chk = 0
 Const HKEY_LOCAL_MACHINE = &H80000002

 Set oLocator = WScript.CreateObject("WbemScripting.SWbemLocator")
 Set oService = oLocator.ConnectServer(, "rootdefault")
 Set oClass = oService.Get("StdRegProv")

 oClass.GetStringValue HKEY_LOCAL_MACHINE, "SOFTWARESky ProductSKYSEAClientViewScvClient", "Version", sRet

 '未インストールの場合NULLが帰ってくるので、Nullの場合は0化
 if isnull(sRet) = false then Func_SkySea_Existing_chk = 4

 'Str_logs = Str_logs  & "Func_SkySea_Existing_chk()が実行されました。実行結果: " & Func_SkySea_Existing_chk & vbcrlf


end function

'----------------------------------------

function Func_LANScope_Existing_chk()

 'LANSCOPE部は後で何も考えずに消せるように...
  Func_LANScope_Existing_chk = 0

 '###  削除対象のアプリケーション名(アプリの追加と削除で表示されるもの
 '### Func_LANScope_Existing_chkの初期値は0
 '### LANScopeは64bitの場合WoWの下に入る
 'LANScope レジストリパス
 '# 32bit/64bitでレジストリパスが異なる
 '"HKEY_LOCAL_MACHINESOFTWAREWow6432NodeMicrosoftWindowsCurrentVersionUninstallLanScope Cat MR"
 '"HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindowsCurrentVersionUninstallLanScope Cat MR"

 Reg_WoW = "Wow6432Node"
 Reg_Str = "SOFTWAREMicrosoftWindowsCurrentVersionUninstallLanScope Cat MR"
 if Int_OS_Bit = 64 then Reg_Str = replace(Reg_Str, "SOFTWARE", "SOFTWARE" & Reg_WoW )

wsh.echo "Reg_Str: " & Reg_Str

 Const HKEY_LOCAL_MACHINE = &H80000002

  'ローカルコンピュータに接続する。
 Set oLocator = WScript.CreateObject("WbemScripting.SWbemLocator")
  Set oService = oLocator.ConnectServer(, "rootdefault")
  'クエリー条件をWQLにて指定する。
 Set oClass = oService.Get("StdRegProv")

  '文字列値
 oClass.GetStringValue HKEY_LOCAL_MACHINE, Reg_Str , "DisplayName", sRet
wsh.echo   "RegisteredOwner(文字列値): "  & sRet

 if isnull(sRet) =false then Func_LANScope_Existing_chk = 2

 'Str_logs = Str_logs  & "Func_LANScope_Existing_chk()が実行されました。実行結果: " & Func_LANScope_Existing_chk & vbcrlf

end function

'----------------------------------------

Function Func_OSbit_chk()
'OSビット数判定。戻り値はINT型
'初期値は0
'サーバOSは処理対象外として0を返す

strComputer = "."
Set objWMIService = GetObject("winmgmts:" & strComputer & " ootcimv2")
Set colItems = objWMIService.ExecQuery("Select * from Win32_OperatingSystem")
Set colItems2 = objWMIService.ExecQuery("Select * from Win32_QuickFixEngineering")
For Each objItem in colItems
 Select Case objItem.ProductType
  Case 1 'Workstation
   'WScript.Echo strVersion & strEdition & strServicePack & " " & objItem.OSArchitecture
   '文字列操作で32bit/64bitの数字のみを返す
   Func_OSbit_chk = Cint(replace(objItem.OSArchitecture," ビット",""))
  Case 2,3 'Serverはめんどくさいから数字だけ返す
 End Select

 Str_logs = Str_logs  & "Func_OSbit_chk()が実行されました。実行結果: " & Func_OSbit_chk & vbcrlf
 

Next

 

end Function

Function Func_Get_Hostname ()

 Set objNetwork = CreateObject("WScript.Network")
 Func_Get_Hostname = objNetwork.ComputerName
 Set objNetwork = Nothing
 
 Str_logs = Str_logs  & "Func_Get_Hostname()が実行されました。実行結果: " & Func_Get_Hostname & vbcrlf

end function

Function Func_Get_IP()

 strComputer = "."
 Set objWMIService = GetObject("winmgmts:" & strComputer & " ootcimv2")
 Set colItems = objWMIService.ExecQuery("Select * From Win32_NetworkAdapterConfiguration Where IPEnabled = True")
 For Each objItem in colItems
      For Each objAddress in objItem.IPAddress
          Func_Get_IP = objAddress
      Next
 Next

 Str_logs = Str_logs  & "Func_Get_IP()が実行されました。実行結果: " & Func_Get_IP & vbcrlf


end Function

Function Func_Wait_timer()

 '15~90秒待ち
 Randomize
 Func_Wait_timer = int(100 * rnd * 1000+15)
 wscript.sleep Func_Wait_timer
 
end function

 

VDIテンプレート

VDIテンプレートのWindowsに関する設定関係ですが、正直どのようにまとめるか悩んでいたところがあります。

設定としては2種類、1つはコンピュータ(OS)に関する設定、もう一つはユーザプロファイルに関する設定です。OSに関しては実際に設定したりレジストリを編集するなりでよいですが、ユーザプロファイルに関わる設定に関してです。
悩んでいたのはユーザプロファイルのほうなのですが、方法としては3種類、もしくはその全てを採用することになる点をどのように説明しようかと考えていました。


『ユーザプロファイルの設定』
1.Sysprepを利用する
 PCの展開をしている方であればsysprepはご存知だと思いますし、紹介しているサイトはいくらでもありますので簡単にしますが、Windows標準のsysprep.exeを利用するとローカルAdministratorのプロファイルが.Defaultにコピーされますのでこれを利用して初期値を設定する方法があります。

ただし、Windows 7の場合sysprepが全プロファイルのファイル容量上限があったり、数回実行すると実行出来なくなったりする問題があります。また、VDIの場合sysprepした後にテンプレート化を行って展開した際にエラーで展開できない(Windowsが起動しない)場合もありますのでできるだけ問題を最小化するためスナップショット取得->sysprep->デプロイテストを行うことと、テンプレのイメージを更新する際にはスナップを戻すのを心掛けたほうがよいと思います。

上記の問題があるからこそ人によってはsysprepを利用した設定方法を推奨しない場合もあると思ったほうがよいでしょう。

2.ローカルポリシを利用する

3.Active Directoryのグループポリシを利用する
 ローカルポリシとグループポリシについては性質が近いのでまとめます。
 OSの設定とユーザの設定とあることと、PC再起動やリログインによりポリシーが再反映する点が利点です。

一方でドメインコントローラの調子が悪い(負荷が高い場合も)、PCの調子が悪い場合にはグループポリシーが適用されないケースがあります。また、ローカルポリシはグループポリシで上書きされますのでローカルポリシで設定し、グループポリシでも同じ設定を入れておくと、あとでフルクローンのパラメータを変更したい場合はグループポリシでまとめて変更する方法が有効です。


この観点から、可能であれば上記2つを両方採用するほうが望ましいですが、sysprep後にデプロイできない場合もありますので、その場合はグループポリシで設定することが望ましいです。

追記になりますが、Windows XPで利用できたプロファイルのコピーですがコピーボタンを有効にするソフトなどがありますが、それらを利用してDefaultプロファイルを書き換えるとOffice製品での参照先パスに異常が発生し、テンプレートファイルが開けない場合がありますのでこれらのプロファイルを上書きする方法は推奨できません。