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

契約中の.infoドメインに対するAfilias社からのドメイン一時停止通知

保有中の.infoドメインに対して、レジストラから品質・安定性維持の目的から、ドメイン名の一時停止を行う旨の連絡が届きました。
.infoドメインの一時停止を回避するには、正当な運用用途を証明できる内容をAfilias社へ連絡する必要があるようです。

調べてみると、去年の2014年には結構通知が来ていたようで、ちょくちょくあるようです。
nonki@rNote – infoドメイン?の落とし穴
「ドメインに対する廃止通知」がやってきた│ハニカム

引用されていた通知内容は下記になります。
ご参考)Afilias社から弊社への通知引用
------------------------------------------
As you know, Afilias continuously monitors names in this TLD for any signsof abuse
that may violate its Anti-Abuse Policy (http://info.info/about/afilias-anti-abuse-policy )
or indicate potential violations of the Registry-Registrar Agreement (RRA).

Domain abuse creates security and stability issues for the registry, registrars, registrants,
and Internet users in general, and must therefore be eliminated insofar as possible.

The following registrants have recently registered domains that have been confirmed
as engaging in or associated with spam activity:

※ この箇所にお客様のドメインを指す情報が記載されています

Each of these registrants currently have domain(s) appearing on
spam domain block lists, nameserver blacklists, and/or IP blacklists.
------------------------------------------

もともと今回通知されていた.infoドメインについては、Value Domainのオークション機能にて落札したものでした。サイト自体、2013年6月にWordPressをインストールして、Hello world!のまま放置していたものです。
放置中に、xmlrpc.phpからスパムメールが送信された可能性も否定できず、また使用していないドメインだったため、今回はそのまま終了でもよいかなぁと考えています。

どちらにせよ、今後は.infoドメインの新規取得はやめようと思います。
せっかく育てたサイトが、こんな形で無くなるのは嫌ですしね!

C#.NETのHttpClientにてCookieを使った通信を行いたい

アプリケーションでWeb上の操作を疑似的に行いたい時などで、クッキー情報を取り出して値を確認したい時などがあります。
そういった場合は、HttpClientHandlerのUseCookiesを有効にしてあげれば、あとは.Netがよきに計らってくれるらしい。
基本的にはtoriimiyukkiの日記さんに書かれていることですが、個人的な用途としてメモ書きです。


// クッキーを使いたいためUseCookies = trueに設定
using (var handler = new HttpClientHandler() { UseCookies = true })
using (var client = new HttpClient(handler) { BaseAddress = new Uri("https://yamahide.biz/") })
{
// ヘッダーの設定
client.DefaultRequestHeaders.Clear();
client.DefaultRequestHeaders.Add("User-Agent", "Mozilla/5.0 (Windows NT 6.1; rv:35.0) Gecko/20100101 Firefox/35.0");
client.DefaultRequestHeaders.Add("Accept", "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8");
client.DefaultRequestHeaders.Add("Accept-Language", "ja,en-us;q=0.7,en;q=0.3");
client.DefaultRequestHeaders.Add("Referer", "https://yamahide.biz/login/");

// GETでリクエスト
var result = client.GetAsync("https://yamahide.biz/login/").Result;

// POSTの内容を作成
var content = new FormUrlEncodedContent(
new Dictionary
{
{ "UserID", "user01"},
{ "PASSWORD", "Passw0rd"},
});
// POSTでリクエスト
result = client.PostAsync("https://yamahide.biz/login/", content).Result;

// クッキーの値を抜き出す
CookieCollection cookies = handler.CookieContainer.GetCookies(new Uri("https://yamahide.biz/login/"));
string ASPNETSessionId = "";
foreach (System.Net.Cookie cook in cookies)
if (cook.Name == "ASP.NET_SessionId")
{
ASPNETSessionId = cook.Value;
}
}