キーボードの誤認識対応


状況

OS は Windows11 で、時折スマホから RDP して利用しています。
その後、該当端末のコンソールでログインしても、キーボードは通常通り入力可能でした。
ただ、その時は Windows Update が走った直後らしく、RDP したあとのコンソール利用で入力が英語キーボードとして動いていました。

スマホからの RDP で、この時、スマホ接続のキーボード等は利用していません。
なので RDP のソフトウェアキーボードに疑義が持たれます。

ポイントとしては、OS アップデート直後に RDP したことによるキーボードレイアウトの誤動作になります。

対策

対処策

調べてみましたが、Windows11 での対処が情報として少ないですね。
今回は、最終的にハードウェアキーボードレイアウトの変更で対処できました。

予防策

Microsoft に文句言うくらいしか思いつきません。

対処

ということで、今回行った対処について。
設定反映には再起動が必須なので、何か作業中なら全部保存して閉じておく必要があります。

流れとしては、次の通りです。
  1. ハードウェアキーボードレイアウトの変更
  2. 再起動
  3. ハードウェアキーボードレイアウトの変更
  4. 再起動
なんで同じことを繰り返してるのかって?
同じことを繰り返さないと直らかなかったからです。

ハードウェアキーボードレイアウトの変更(1回目)

システムへのアクセス
Win + i で、システムへアクセスします。
次のような、システム画面が出てきますので、「時刻と言語」をクリックします。
システム
システム 画面
「キーボードレイアウトの変更」へのアクセス
次のような画面で、「言語と地域」をクリックします。

時刻と言語
時刻と言語 画面

次のような画面で、言語の「日本語」から … メニューをクリックして「… 言語のオプション」をクリックします。

時刻と言語>言語と地域
時刻と言語>言語と地域 画面
次のような画面で、キーボードレイアウト:日本語キーボード(106/109 キー) の「レイアウトを変更する」 をクリックします。

時刻と言語>言語と地域>オプション
時刻と言語>言語と地域>オプション 画面
「ハードウェアキーボードレイアウトの変更」での設定
次の画面で、キーボードレイアウト:日本語キーボード(106/109 キー) をクリックします。

なお、日本語キーボードとして登録されているのに OS は英語キーボードとして動いているので、この設定項目名ではなく、設定内容がおかしくなっていると推測されます。
一度別のものに変更して、正しいものに設定し直す作戦です。
ハードウェア キーボード レイアウトの変更(日本語)
ハードウェア キーボード レイアウトの変更(日本語) 画面

私の場合は「接続済みキーボード レイアウトを使用する」を選択しましたが、目的を考えれば英語キーボードでも問題ないと思います。

ハードウェア キーボード レイアウトの変更(選択画面)
ハードウェア キーボード レイアウトの変更(選択画面) 画面

次の画面で、「今すぐ再起動する」をクリックすると、再起動されます。

ハードウェア キーボード レイアウトの変更(変更後)
ハードウェア キーボード レイアウトの変更(変更後) 画面

ハードウェアキーボードレイアウトの変更(2回目)

同じことをもう一度行います。

違うことは、もとの「日本語キーボード(106/109 キー) 」を選択するところだけです。
また再起動します。

確認

私の場合は、これで元に戻りました。

windows の資格情報削除

Windows の資格情報削除

Windows を利用していると Teams のログインなどで登録されることがあるアカウント情報。
消すならWinキー→資格といれて資格情報にアクセス

資格情報マネージャーへのアクセス方法

サーチ利用
Win キーから「資格」と入力した状態で、資格情報マネージャーにアクセスできる。
資格情報マネージャー
資格情報マネージャー

ちなみに、英語で Credential Manager らしく、cred を入力してもアクセス可能。
Credential Manager
Credential Manager

アカウント情報削除

アカウントへのアクセス
「Web 資格情報」と「Windows 資格情報」があるが、Teams で利用するアカウントは Windows 資格情報の中にある。
Web資格情報
Web資格情報
Windows資格情報
Windows資格情報
情報削除
Windows 資格情報のなかで、汎用資格情報のなかに「SSO_POP_User:user=xxx@example.co.jp」のような内容があるので、それを開く。
SSO_POP_User
資格情報の例
この「削除」をクリックすると、次の削除確認がポップアップする。
削除確認
削除確認
ここで「はい」を選択すれば、資格情報が削除される。

実行中スクリプトの編集

実行中スクリプトの編集



まず、スクリプトの実行についておさらいしておきます。

スクリプトは、テキストを読んで命令文を逐次解釈し、記述された順番でコマンドを実行するものです。
これはコマンドインタープリタの標準的な挙動です。

そのため、シェルスクリプトも Windows バッチファイルも、実行中にファイルを書き換えたり、消したりするとエラー終了します。

検証方法

検証には、次のようなスクリプトを書くとよいでしょう。
#!/bin/bash
echo "Start"
sleep 30
echo "End"
sleep で待ち時間が発生している間に、End を書き換えたり、追記したり、ファイルを消したりすればよいわけです。

実際にやってみれば、書き換わった後に追記したコードが実行されたり、エラーが出たりと、予想できない挙動を示すでしょう。
そういった理由から誤って実行中にバージョンアップしてしまったり、自分自身を書き換えてしまうバグを作りこんでしまったときには、非常に困るわけです。

不意の修正に強くするためには

では、対策を考えてみます。

そもそもの仕様としてファイルへの読み込みが発生するので、実行中スクリプトの修正に書き換えを行わせないための策は、根本的にありません。

ですが、少しでも強くする方法はあります。
(1) 適切な権限を設定する
「書き込み権限があるので書き込めるのだ」という発想で、書き込み権限を消しておく方法です。

$ sudo chmod -w sample.sh

頻繁に修正の発生しない、もしくは発生しては困る本番環境では、考慮されているものと思われます。
デメリットとしては、修正を行う時は毎回権限を付与する、もしくは sudo を利用して書き換えるといった手間や権限の乱用に繋がる点でしょう。
(2) 書換を検知する
スクリプト自体に、自身の書き換えを検知させる方法としては、ls や file、stat といったコマンドで自身の更新時刻を管理させます。

頻繁に実行する内容になるでしょうから、関数として呼び出すのが自然でしょう。

Linux bash では、関数にすると環境変数としてセットされるようです。
何が環境変数としてセットされているかは set コマンドで確認できます。

環境変数はメモリに展開されるので、ファイル編集の影響をうけません。
ということは、関数はファイル編集だけならば影響をうけません。

環境変数を書き換える行為(関数の再定義)が必要です。

つまり、スクリプト始めにファイルの更新時刻を環境変数として持っておき、以後は適宜差分をみる方法がとれます。

差分自体は test コマンドで比較すれば、そう難しいロジックを組むことなく実装できるでしょう。


かなり荒々しいですが、次のようなサンプルでも差分検出としては要件を満たせるでしょう。

#!/bin/bash
before="$(ls -l $0)"

functionDiff() {
  after="$(ls -l $0)"
  [ "${before}" == "${after}" ] || echo "NG"
}

functionDiff
また、md5sum といった、ファイルの破損や編集を検知するためのチェックサム関係コマンドを利用するのも良いです。

(3) メモリに読み込む 1
関数はメモリに置かれた内容が実行されるので、影響を受けにくいことは前段で記述しました。
ならば、出来るだけ関数にしてしまえば影響を極力排除できるだろう、という発想です。

関数などは別ファイルに記述できるので、究極、制御系(判断分岐や関数実行)しかないスクリプトになります。
関数名に気を遣えば抽象的な構文になるので、かなり読みやすいスクリプトになると思います。

外部ファイル /tmp/example.conf

### example.conf

# Parameter or Variable
example="EXAMPLE"

# Function
exFunction() {
  echo "${example}"
}

実行ファイル /tmp/example.sh

#!/bin/bash
### Script name: example.sh
# Include
. ./example.conf

# Main
exFunction

(4) メモリに読み込む 2
スクリプトに記載されている内容を、一度メモリに読み込んでおくという手法も取れます。

実体としては、一度、実行したいスクリプトを変数に読み込んで、echo してあげて1行ずつ解釈していく方法になるでしょう。


実行したいスクリプト /tmp/example.sh
#!/bin/bash
# script name : example.sh
echo a
echo b
echo c

注意事項として bash の echo では、変数を展開するときダブルクォートがあるかどうかで、出力形式が変わります。
具体的には、次の通りです。

envbar=$(cat /tmp/example.sh)
$ echo ${envbar}
#!/bin/bash # script name : example.sh echo a echo b echo c
$
$
$ echo "${envbar}"
#!/bin/bash
# script name : example.sh
echo a
echo b
echo c

余談ですが、変数名のブラケット と は無くても大丈夫です。付けておくと、変数展開がしやすいのでお勧めです。
なお、シングルクォートでは変数展開が行われません。

サンプルとしては、次の通りです。

example.sh を実行するコマンド

envbar=$(cat /tmp/example.sh)
$ echo "${envbar}" | bash -
a
b
c

まとめ

実行中の書き換えに対する予防策は、アクセス権限だったり検知機構だったり、ファイル内容の取得だったりといろいろ示しましたが、意図して起こした場合には無力です。

複数の防御手段を併用するのが、一番強力です。

感想

変数への読み込みを行うメリットは、メモリに展開される関係で処理速度が段違いに早くなることも考慮できるでしょう。
特に、HDD といった比較的遅い媒体からの読み出しとオンメモリでは、比較になりません。

変数は int (32bit) で定義されていることが多いようなので 4GB までは対応していそう*1です。

変数への取り込みは、スクリプト内で変数へ読み込んでおいて、1行ずつデータを解析していくにも良さそう。

技術の引き出しが多いことに越したことはないので、他にも方法があれば教えていただきたいです。

*1 : メモリに展開する以上、メモリの最大容量にも依存するものと思われる。

Excel VBA

2021/05/22 21:45 OS別::Windowsその他::技術情報

Excel VBA


Excel のバージョン情報

このページを作成する際に使った、Microsoft Excel 情報です。

バージョン 2104 (ビルド 13929.20372)
Excel バージョン情報
Excel バージョン情報

Microsoft 365 のサブスクリプションを契約しており、基本的には最新版*1を利用しています。
メールアドレスなど、アカウント系の情報は消しています。

Excel VBA とは

現在発売されている Microsoft Excel は、標準でマクロ機能が存在します。

いくつか Tera Term と連携するネタがあるので、それを記載したいと思います。
その前に、VBA を利用できる環境にするための設定から。

VBA の有効化

Excel オプションを開く
Excel VBA は、オプションからリボンを有効化することで簡単に利用することができるようになります。

まず、メニューバーから「ファイル」を選択します。

Excel 起動
Excel 起動

左ペインから「オプション」を選択します。

オプション選択
オプション選択
マクロを利用する設定
Excel のオプションが表示されるので、左ペインから「トラスト センター」を選択します。
ここで、右ペインに「トラスト センターの設定」が表示されていることが確認できます。

トラスト センターの設定
トラスト センターの設定

メッセージバー
トラスト センターでは、メッセージ バーが表示されると思います。

「ActiveX コントロールやマクロなどのアクティブ コンテンツがブロックされた場合、すべてのアプリケーションにメッセージ バーを表示する」にチェックが入っていることを確認します。

メッセージ バーの表示
xxxx

何かの拍子にブロックされても分かりませんので、入っていなければいれておきましょう。
マクロの設定
左ペインから「マクロの設定」を選択します。

ここでは、右ペインに出てくるマクロの設定から「すべてのマクロを有効にする(推奨しません。危険なコードが実行される可能性があります)」のチェックボックスを有効にします。

自分がいつ、どのように作った VBA マクロなのかは分かると思いますので、有効にしても問題ないという理屈です。

思い当たらないファイルは、基本的に開かなければ問題になりません。

マクロの設定
マクロの設定

「警告を表示してすべてのマクロを無効にする」を選択しても良いでしょう。
VBA マクロが入っている Excel ファイルを開いたときに、画面上部に薄い黄色で「セキュリティの警告 マクロが無効にされました。[コンテンツの有効化]」がでます。

この場合、そのファイルは「コンテンツの有効化」を押して実行を許可しなければ動きません。
逆に言うとマクロを動かすために許可すればよいので、確認するという観点では推奨できるものと思います。


このページの趣旨からは外れるため解説はしませんが、安全にマクロを利用する場合はデジタル署名を行うことが可能です。
デジタル署名を行うと、誰が VBA マクロを含むファイルを作成したかがシステム的に分かるため、安全になります。


「OK」を選択して、Excel のオプション画面に戻ります。

マクロを開発する設定
Excel のオプションが表示されたら、左ペインから「リボンのユーザー設定」を選択します。
ここで、右ペインに「□開発」が表示されていることが確認できます。

開発 有効化ボタン
開発 有効化ボタン

「開発」にチェックをつけて「OK」を押します。

開発 有効化状態
開発 有効化状態

Excel の通常画面に戻ります。
この時、メニューバーに「開発」が表示されていれば、設定できています。

メニューバーの開発
メニューバーの開発

VBA 標準モジュールの追加

開発メニューを選択すると、リボンが表示されます。
VBA でコードを書きたいときは、ここで「Visual Basic」を選択します。

開発リボンの内容
開発リボンの内容

「VBAProject(Book 1)」でも「Microsoft Excel Object」でも構わないのですが、右クリックして「挿入」→「標準モジュール」と進みます。

標準モジュールの追加
標準モジュールの追加

Excel VBA として、標準モジュールが追加されました。

追加した標準モジュールの内容
追加した標準モジュールの内容
VBA マクロのある Excel ファイルの保存
標準モジュールを追懐したファイルは、拡張子「.xlsm」で保存します。
VBA マクロが有効なファイルはサイバー攻撃に利用されることが多いので、注意する必要があるためです。

VBA 有効ファイルの保存
VBA 有効ファイルの保存

VBA が動作する Excel ファイルは、作成日付といったプロパティや、誰が作ったものなのかといった信頼できる情報をもとに開くようにしましょう。

*1 : 更新タイミングによっては、少し古いバージョンだったりもします。

シェルコマンド言語


シェルコマンド言語の雑な説明

このページでは、シェルコマンド言語の使い方、ひいてはシェルスクリプトを記述するための前提となる知識を、雑に紹介するところから始めます。
一応、このツイートと関連しますw

シェル

ある程度馴染みがあるであろう Linux で説明します。

Linux は Linus Torvalds さんがメインとなって開発されている中心的プログラムである Kernel(カーネル) で動きます。
Kernel というのは、たとえばファイルの扱い方だったり、ネットワーク通信の仕方だったりを制御してくれます。

指示すれば制御してくれるのですが、思った通りにはやってくれませんので Kernel そのままでは、人が扱うのに不向きです。
そこで、何らかの形で Kernel に仕事をさせるプログラムが必要になります。

それが、キーボードから 特定の文字列(コマンド) を入力して Enter を押すと Kernel にアクセスすることができる、シェルと呼ばれるプログラムです。
Linux Kernel を包み込む 貝殻(シェル) のようなイメージをすると、良いかもしれません。

つまり Linux におけるシェルとは、コマンドラインインタープリタ(指定した文字列を適宜解釈して実行するプログラム)のことです。
bourne shell とか c shell とかいった、いくつかの種類が存在しています。

このシェルには環境変数と呼ばれる変数があり、暗黙的/明示的に様々な形で利用されます。

なお、シェル自体は Linux が参考にした UNIX で実装されている CUI でもあります。
UNIX の歴史とともにあるプログラムですが、ここでは割愛します。

コマンド

コマンドは、シェル自体にビルトインされているものもありますが、基本的には単一の目的のために作られたプログラムになります。
たとえばシェルで ls というコマンドを実行すると、カレントディレクトリ配下にあるファイルが表示されますが、これは /bin/ls というファイルを実行した結果です。

ls コマンド


type というコマンドは、どのパスで実行しているか以外にハッシュされているかどうかを表示してくれます。
ハッシュされている(位置を記憶している)と、環境変数 $PATH を検索せずにコマンドが実行されることを意味しています。

which というコマンドは、パスのどこに存在するのか教えてくれます。

インタプリタ内部では $PATH に定義されたパスの順に、コマンドと同じファイル名のプログラムを探し、最初に合致したファイルを起動します。
この PATH に . が含まれている場合、カレントディレクトリのファイルも実行対象として検索されます。

コマンド用のプログラムは、目的に沿って格納するディレクトリが分けられています。
そのディレクトリは環境変数 PATH に記述され、コマンド実行時に随時*1参照されて呼び出すプログラムが決定されます。

*1 : 場所を予め覚えているコマンドがあるといった一部例外はありますが

シェルコマンド言語

ここでは、シェルコマンド言語についてあれこれ記載します。
UNIX のシェル (CUI) で使うコマンドの仕様のことです。

シェルスクリプト

日本における IT 業界では、シェルコマンド言語で書かれたスクリプトをシェルスクリプトと呼んでいます。
むしろ、シェルコマンド言語というと「コマンドは言語じゃないだろ」と言う人もいるかもしれません。

なんでこんな書き方をしてるかというと POSIX が Shell Command Language と書いているからです。

プログラム言語は、基本的に英語圏で開発されたものなので、英語をもとにしています。
言語の和訳は、つぎのように行われています。

programming language → プログラミング言語
C Language → C 言語

なら Shell Command Language は シェルコマンド言語でしょう。
シェルコマンド言語で書いたスクリプトは、シェルスクリプトで良いと思います。

POSIX

では、POSIX というのは何か。

現在の POSIX とは UNIX を名乗る OS に共通する仕様を決めたものです。

正式名称を Portable Operating System Interface for UNIX *2 と言います。
2020 年8月現在、UNIX という商標をもち POSIX という仕様を策定している The Open Group という業界団体が仕様を公開しています。

https://publications.opengroup.org/

なお、規格としては IEEE になっているので IEEE Std 1003.1-2017 という表記になっています。

UNIX と名乗る OS は、POSIX 仕様に準拠したうえで、ライセンス料を支払う必要があります。

ちなみに Linux は POSIX に準拠していますが、ライセンス料は支払っていないので UNIX ではない、という立ち位置です。
また、Linux は Linus Torvalds が商標を持っています。

最新は 2018 Edition ですね。
何年か毎に更新されるので、参考までに。

シェルコマンド言語

前置きが少し長くなりましたが、シェルコマンド言語仕様へのアクセスは次の URL になります。

https://pubs.opengroup.org/onlinepubs/9699919799/
main
3ペインの左上から Shell & Utilities をクリックします。
すると左下ペインに、対応するメニューが表示されます。
Shell and Utilities
メニュー内容
1. Introductionどんなコマンドとユーティリティを提供するのか、その前置き
2. Shell Command Languageシェルコマンド言語の定義
3. Batch Environment Servicesバッチジョブへ提供する機能の定義
4. UtilitiesUNIX が提供する機能やコマンドの説明

*2 : なお for UNIX の部分は後付けと聞いています。

シェルスクリプト

シェルスクリプトは、シェルコマンド言語で書かれたスクリプトファイルです。

シェルスクリプトというと長いので、省略してシェルと呼ばれることもあります。
文脈で判断してください。

シェルスクリプトの書き方

シェルスクリプトはテキストなので、テキストエディタで記述します。
ファイルの形式
基本的には、コマンドを書いてファイルに保存し、bash に引数として読み込ませれば実行されます。

ファイル単体で実行するためには、最低限、以下の書き方をする必要があります。
shebang
ファイルの1行目に、つぎの文字列を書きます。
#!/bin/bash
これを shebang (シバン等と読む)と言い、UNIX の処理系ではインタープリタ(実行プログラム)を指定するものとして利用されています。
#!/bin/perl
であれば perl スクリプトになります。
bash を指定するので、bash スクリプトです。

sh や ksh 等ありますが、現在の POSIX に準拠したシェルは bash くらいなので、ここでは bash を利用します。
文字コード
文字コードは、基本的に ASCII であれば問題なく動きます。

UTF-8 を指定する場合でも、BOM (Byte Order Mark) やマルチバイト文字がなければ、実質上は ASCII と同じになるので問題なく動きます。

BOM を指定すると、スクリプトとしてはファイルの先頭に余計なバイナリが差し込まれることになります。
Kernel 側で実行を制御できなくなり、エラーで返るので注意してください。

また、マルチバイト文字も一部のコードが別な制御コードと混同されて、エラーを返すことがあります。
コメントであっても、できれば使わないに越したことはありません。

その点を認識して、注意してコメントを書くという運用を行うのであれば、問題にはならないと思います。
改行コード
文字コードには関係なく (ASCII でも UTF-8 でも EUC でも)、改行コードは LF である必要があります。

シェルスクリプトとして CR+LF を利用した場合は、実行エラーが発生します。

通常、実行するシステムでコーディングを行うことが多く、滅多に問題にはなりません。
外注した場合に改行コードの指定をうっかり忘れると、ほとんどの場合で Windows 端末によるコーディングが行われます。
動かないコードが納品される原因の上位に来るので、細かい点ですが注意しましょう。

FTP での ASCII 送信で、スクリプト単体を送信すれば改行コードが変換されて問題ないのですが、Zip にまとめて送るなどで取り切れないこともあります。
記述方法
テキストファイルなので、テキストエディタで記述します。

Linux なら vi / vim や nano, emacs, vscode 等で書けます。
Windows ではないので拡張子は何でも大丈夫、なんなら拡張子が無くても大丈夫ですが、慣例的に .sh や .bsh 等が使われています。

以下、最も簡単なサンプルとして xxxxx.sh を記述します。
#!/bin/bash
echo 'Hello World!'

実行方法

シェルスクリプトは、実行権限を与えて、コマンドとして利用します。

実行権限は、次のコマンドで与えることができます。
$ chmod +x xxxxx.sh
権限が付与できたら、次のように実行します。
$ ./xxxxx.sh
Hello World!
$ 
以下、実際に実行したところです。
サンプル スクリプト(実行権限あり)


また、実行権限を付与しなくても、シェルスクリプトとして実行する方法はあります。
サンプル スクリプト(実行権限なし)


これは、bash にスクリプトファイルを引数として読み込ませて、実行させているためです。

サンプルでは ./ を付けるものと付けないものがあり、なぜ分けているのか疑問に思われたでしょうか?

Linux / UNIX では、カレントディレクトリを示すのに . が利用されます。
カレントディレクトリのファイルを示すためには、ファイル名と区別する意味で / による階層構造を示す必要があります。

現在のディストリビューションでは $PATH にカレントディレクトリを示す . が含まれていません。
そのためカレントディレクトリにあるスクリプトは ./ がないとコマンドとして認識されません。

サンプル スクリプト(PATH指定なし)


これは、カレントディレクトリに ls 等のよく使うコマンド名でシェルスクリプトをホームディレクトリに配置されてしまうと、悪意あるコードを実行させることが容易になるからです。

シェルスクリプトの入門としては、以上のことに気を付ければ良いと思います。