Windowsのeventcreateコマンドにてソースパラメーターのエラーが出たときの対処

Windowsのコマンドプロンプトにて、イベントを記録するためにeventcreateコマンドを実行したときに、すでにあるイベントソースを指定すると次のようなエラーが表示されることがあります。

ERROR: Source parameter is used to identify custom applications/scripts only (not installed applications).
eventcreate /L Application /T Information /SO "hoge" /ID 1 /D "Information write."
エラー: インストールされているアプリケーションではなく、カスタム アプリケーションまたはスクリプトを識別するためだけに、ソース パラメーターが使用されます。

これは作成されているイベントソースへ、ソースを作成したプログラムからしかアクセスできないため起きるようです。今回の場合はPowerShellにて下記コマンドでソースを作成していました。
New-EventLog -LogName Application -Source hoge

修正するには、レジストリエディタより対象ソースにCustomSourceという名前で1の値を設定すればよいようです。今回はアプリケーションイベントのhogeというソースなので下記になります。
eventcreate_Source_error_2
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\Application\hoge]
"CustomSource"=dword:00000001

その後、もう一度eventcreateコマンドを実行すると成功しました。
eventcreate_Source_error_3
eventcreate /L Application /T Information /SO "hoge" /ID 1 /D "Information write."
成功: 種類が 'Information' のイベントが、'Application' ログ内に、'hoge' をソースとして作成されました。

イベントログのアプリケーションにPerflibエラーID:1008が記録されるときの対処

システム起動時やパフォーマンスログ取得開始時に次のようなエラーが記録されることがあります。
Application_Perflib_1008_BITS
ログの名前: Application
ソース: Microsoft-Windows-Perflib
イベント ID: 1008
レベル: エラー
説明:
サービス "BITS" (DLL "C:\Windows\System32\bitsperf.dll") の Open プロシージャに失敗しました。このサービスのパフォーマンス データは利用できません。データ セクションの最初の 4 バイト (DWORD) に、エラー コードが含まれています。

これは、パフォーマンスモニタのカウンタ読み込みに失敗しているときに、利用できないパフォーマンスカウンタオブジェクトがある場合にエラーメッセージが発生します。
そのため、影響があるサービスのパフォーマンスモニタのカウンタをインストールまたは再インストールしてあげれば解消します。使わない場合はアンインストールもOKです。

今回の”BITS”の場合は、管理者として実行したコマンドプロンプトで下記を実行すれば直ります。
cd C:\Windows\inf\BITS\0411
lodctr bitsctrs.ini

Application_Perflib_1008_BITS_lodctr

備考:Application Center でパフォーマンス データ カウンタに関する Perflib のイベント ID 1008 エラー メッセージが表示される
https://support.microsoft.com/ja-jp/kb/299059

Windows Update にて斜体(イタリック)と普通のものが表示される

Windows Updateを実行しようとしたときに、特定の修正プログラムだけ、フォントが斜体(イタリック)で表示されることがあります。
WindowsUpdate_italic
これはオプションでの、お勧めアップデートが斜体で表示されるようです。
あくまでお勧めアップデートなので、OSのセキュリティ修正や安定性などは修正されません。ヘルプファイルの更新だったりドライバの更新だったり、特定の組み合わせ時に動かない処理を修正しているようです。

特にこだわりが無ければすべてのアップデートを実施し、あまり変更したく無い場合は重要なアップデートだけを適用していけばよいかと思います。

Windows Server 2012のXenAppやRemoteAppでテーマファイルが適用されない

Windows Server 2008や2012のローカルグループポリシーにて「特定のテーマを読み込む」を設定しても、XenAppの公開アプリケーションやRemoteAppのユーザにテーマが適用されない事象が発生します。
win2012_theme_1
テーマが適用されていないユーザが、サーバにリモートデスクトップ接続(mstsc)にてログオンするとテーマファイルが適用されます。
この事象は、テーマファイルの初期化をexplorer.exeが行っているため発生します。XenAppやRemoteAppはデスクトップ表示を行う必要がなく、explorer.exeが自動起動することはありません。

explorer.exeは新しいユーザがログオンしたタイミングで、ntuser.datを作成・読み込みした後にActive Setupといわれる初期化処理を行います。
Active Setupでのテーマファイル適用は下記コマンドにより実行されています。
"C:\Windows\System32\regsvr32.exe" /s /n /i:/UserInstall C:\Windows\system32\themeui.dll
そのため、ログオンスクリプトにてコマンドを実行してあげればテーマファイルがユーザに適用されます。

コマンドプロンプトを管理者として実行して「gpedit.msc」を起動して、[ユーザーの構成]の[Windowsの設定]にある「スクリプト(ログオン/ログオフ)」の「ログオン」を開きます。
win2012_theme_2
「追加」ボタンを押して、先ほどのコマンドを下記のように入れてあげれば設定完了です。
win2012_theme_3

設定をすぐに反映する場合には、コマンドプロンプトを管理者として実行して「gpupdate /force」を実行してください。

・Things to do when troubleshooting Internet Explorer Terminal Server and Profiles issues.
https://blogs.msdn.microsoft.com/askie/2012/09/13/things-to-do-when-troubleshooting-internet-explorer-terminal-server-and-profiles-issues/

BlatJをWindows Server 2012で使用した時に送信時間が1時間ずれる時の対処

BlatJとは、Windows NT時代からよく使われているバッチファイルから任意のメールアドレスにメールを送ることのできる実行ファイルです。
最近はVBScriptやPowerShellにて送付することが多いと思うので出番は少ないですが、環境リプレース時にバッチファイルの改修が面倒な際にはそのまま使ってしまったりします。

BlatJはWindows Server 2008やWindows Server 2012でも動作可能ですが、メールを送ると下記のように送信時間が1時間ほどずれてしまいます。
BlatJ_0
もともとWindows NTで動作するものですので、Windowsの夏時間(サマータイム)検出がうまくいかずにこのような事象が出るようです。

対処としては、夏時間を使用しないように設定変更してあげれば可能です。

まず日本時間では夏時間は設定できないため、コントロールパネルの「日付と時刻」より「タイムゾーンの変更」を開きます。
BlatJ_1

タイムゾーンで、例えば「(UTC-08:00)太平洋標準時(米国およびカナダ)」を選択して、「自動的に夏時間の調整をする」のチェックを外して「OK」を押し設定を反映させます。
BlatJ_2 BlatJ_3
もう一度「タイムゾーンの変更」を開き、元の「(UTC+09:00)大阪、札幌、東京」へ設定を戻してあげれば完了です。
BlatJ_4

これでBlatJからメールを送信しても時間がずれなくなります。

ちなみに、タイムゾーンの一覧情報は下記のレジストリに格納されています。
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Time Zones
現在設定されているタイムゾーンは下記に保存されています。
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\TimeZoneInformation

コマンドで「ネットワークドライブの割り当て」ダイアログを表示する

NetworkDrive_add_01
CIFS共有をドライブにマウントする際、通常はコンピューターのツールより「ネットワークドライブの割り当て」を行いますが、この操作を別の処理から呼び出すことができないか調べてみました。

まずプログラムからは、Windows APIの「WNetConnectionDialog」関数を使用すると表示できるようです。
https://msdn.microsoft.com/ja-jp/library/Cc447010.aspx
C#なら下記のようにmpr.dllを読み込んで実行すれば表示できます。
[DllImport("mpr.dll", CharSet = CharSet.Ansi)]private static extern int WNetConnectionDialog(IntPtr HWND, int dwType);
WNetConnectionDialog(this.Handle, RESOURCETYPE_DISK);

単純なプログラムやバッチファイル・VBscriptなどからは、下記コマンドを実行することで表示できます。
Windows 7のコマンドプロンプトにて確認済みです。
RUNDLL32 SHELL32.DLL,SHHelpShortcuts_RunDLL Connect

実行すると、次のように「ネットワークドライブの割り当て」が表示されました。
NetworkDrive_add_02

PowerShellにてCitrix XenDesktop7.6のDCに未登録マシンがないか確認する

最近のソリューションはPowerShellにて管理できるようでして、様々な作業を半自動化することが可能です。
そんなわけで、Citrix XenDesktop/XenAppで少しだけDeliveryController(DC)の状態を取得してみました。

とりあえずテストとして行ったものは、DC上でVDAの情報を取得して結果をイベントログに記録することです。
具体的に何がしたかったかというと、各VDAがどのくらいの頻度で再起動を繰り返しているかを記録することですが、スクリプト書いている途中でめんどくさくなりイベントログに書き込んで終わりにしています。

他にもいろいろ出来そうですが、そのうちいろいろやろうかと思った次第。

#Citrixのスナップインをすべて読み込む
asnp citrix*
#DCにマシンステータスがUnRegistered(未登録)のものがないか問い合わせる
$objUnregMachin = (Get-BrokerMachine -RegistrationState UnRegistered).MachineName
#変数objUnregMachinに何か入っていたらイベントログに書き込む
if ( $objUnregMachin -ne $null ){
[Diagnostics.EventLog]::WriteEntry("XenApp", "$objUnregMachin" , "Warning", 1)
}

備考:Get-BrokerMachine – Citrix eDocs
http://support.citrix.com/proddocs/topic/citrix-broker-admin-v2-xd76/get-brokermachine-xd76.html

Windows Server 2012のRDライセンスマネージャーに表示されるデバイスCAL発行先をエクスポートする

Windows Server 2003ではターミナルサーバーライセンスのPer-Device Client Access Licenseを、Windows Server 2000のリリースキットに収録されてあるLsreport.exeにて実行できました。
そのため同じように、Windows Server 2012に対してLsreport.exeを使用しようとするとエラーが表示され実行できません。
Windows Server 2008まではLsreport.exeが使用できていたので、どうやらそこまでが限界のようです。

リモートデスクトップライセンスマネージャで表示されているのを目コピーしてもよいのですがとてもメンドくさくて、画像ファイルにすると検索ができずにサイズが大きくなります。

それならば他に方法がないかと調べてみると、リモートデスクトップのAPIが公開されていたのでこれを使ってみたらよいかなと実験してみました。
・Remote Desktop Services API
https://technet.microsoft.com/ja-jp/aa383464
Win32_TSIssuedLicenseに様々なクラスがあり、それを呼び出せば普通に値が取得できるようです。

まずはライセンスの種類を取得するため、TSLicenseKeyPackを呼び出して値を記録します。
・Win32_TSLicenseKeyPack class
https://msdn.microsoft.com/en-us/library/aa383803.aspx
var KeyPackScope = new ManagementScope(@"\\" + System.Net.Dns.GetHostName() + @"\root\cimv2:Win32_TSIssuedLicense");
ObjectQuery KeyPackQuery = new ObjectQuery("Select * from Win32_TSLicenseKeyPack");
ManagementObjectSearcher KeyPackSearcher = new ManagementObjectSearcher(KeyPackScope, KeyPackQuery);
ManagementObjectCollection KeyPackCollection = KeyPackSearcher.Get();

そのあと、TSIssuedLicenseを呼び出してライセンスの一覧を取得し、ライセンスの種類は先ほど取得したものと置き換えます。
・Win32_TSIssuedLicense class
https://msdn.microsoft.com/en-us/library/aa383802.aspx
var IssuedLicenseScope = new ManagementScope(@"\\" + System.Net.Dns.GetHostName() + @"\root\cimv2:Win32_TSIssuedLicense");
ObjectQuery IssuedLicenseQuery = new ObjectQuery("Select * from Win32_TSIssuedLicense");
ManagementObjectSearcher IssuedLicenseSearcher = new ManagementObjectSearcher(IssuedLicenseScope, IssuedLicenseQuery);
ManagementObjectCollection IssuedLicenseCollection = IssuedLicenseSearcher.Get();

あとは取得したデータを好きにConsole.WriteLineで出力すれば、リリースキットのLsreport.exeと同じようなものが作れました。
一応、サンプルを置いておきます。エラー処理はほとんどしていないので、実際に使うときはもう少しtry/catchを入れたほうがよさそうです。

実行ファイル:LSReport_bin
ソースコード:LSReport_prj