misc.log

日常茶飯事とお仕事と

バッチファイルからOracle DBのexpdp.exeを実行する

バッチファイルから、Oracle DBのデータエクスポートコマンド「expdp.exe」を、非管理者ユーザーが管理者権限で動かせるようにする必要があったので、少し模索してみた際のメモを残しておきます。

処理の概要

単にコマンドを発行するだけであれば簡単だったのですが、要件として下記の処理を夜間処理でスケジュール実行する流れの中でexpdpを実行する必要がありました。

  1. 前回のダンプファイルやログファイルを退避する。
  2. expdp.exeを実行してスキーマの内容をダンプする。
  3. ダンプファイルが存在することを確認する。

問題は2番目の部分。ここを管理者権限で実行する必要があったのですが、ざっとネットで調べたところ方法は2つ。

  • RunAsコマンドでAdministrator権限を使ってコマンドを実行する。
  • PowerShellの「-verb runas」でコマンドを実行する。

実際に試してはいないのですが、ブログなどでの情報では、どうやらPowerShellを使った場合ユーザーアカウント制御の問合せメッセージが表示されるとのこと。サーバーで動く夜間処理でそれは困るので、まずは消去法でRunAsを使う方式を調べることに。

RunAsの問題1:コマンドを起動したら自分は終わってしまう

RunAsはWindowsに備わっているコマンド(runas.exe)なので、実行方法も何通りか考えられます。パッと出てきた方法それぞれについて問題点等を記載しておきます。

  • バッチファイルから直接RunAsとして動かす …… 下記のように、RunAs /user:Administrator コマンド名、でコマンドを実行できますが、RunAsは指定されたコマンドを実行すると、その終了を監視せずに「終わったよ」とバッチ処理に戻ってしまうので、上記の要件に書いた「ダンプファイルの存在確認」がダンプ中に実行されてしまい、エラーになります。

runas /user:Administrator "expdp (引数)"

  • バッチファイルからstart /wait コマンドでRunAsを指定する …… バッチファイルで使えるコマンド「start」は、引数 /wait でその結果を待つことができます。しかしstartが呼ぶのはRunAsで、RunAsは自分が動かすプログラムにGoという指示を出した時点で、startコマンドに「終わったよ」と返事してしまうため、これも使えませんでした。

start /wait runas /user:Administrator "expdp (引数)"

  • VBScriptのRunコマンドでRunAsを動かす …… RunAsの部分をVBScript(拡張子.vbs)のスクリプトで記述し、WScript.shwllのRunメソッドで「終わるまで待つ」指定でRunAsとexpdpを呼び出し。これをバッチファイルから呼べば……とも思いましたが、やはりRunAsがexpdpを呼んだ時点で終了となってしまいダメでした。

set wsh = WScript.CreateObject("WScript.Shell")
wsh.Run "runas /user:Administrator ""expdp (引数)"" ", 10, True

最終的に、下記teratailのQAにあった方法でrunasが呼び出すexpdpのダンプ処理完了を検知して、バッチを先に進めるという処置を組むことが出来ました。
teratail.com

方法は下記の通りです。

  • 処理を主処理と副処理に分割し、副処理バッチの中でexpdp.exeを実行する。
  • 主処理側では、一応 start /wait でRunAsを実行する。
  • RunAsの実行後、waitfor xxx(xxxはあらかじめ決めた文字列)で副処理終了シグナルを待つようにする。
  • 副処理の中ではexpdpによるダンプ処理を記述し、その後に waitfor /si xxx で待っている主処理に終了シグナルを送るようにする。

これで、主処理のRunAsはすぐに終了するもののwaitforでバッチ処理は待ち状態に。一方、副処理は時間が掛かるダンプ処理をじっくりと実行した後、終わったら主処理に waitfor /si で終了の通知を送って、主処理が先に進み始めます。

実際の処理記述は下記のようになります。まずは主処理バッチ。

start /wait runas /user:Administrator 副処理バッチ
waitfor xxx
(ファイル存在確認処理)

次に副処理のバッチ。

expdp (引数)
waitfor /si xxx

RunAsの問題2:パスワードを聞いてくる

これが致命的でした。RunAsではユーザー名は指定できますが、パスワードは指定できません。流石に平文でスクリプトに埋め込まれてはたまらないからでしょう。で、どうなるかというと、パスワードを入力してください、という問合せメッセージがコマンドプロンプト上に表示されます。

これについては対応方法は大きく2通りでした。

  • runasのオプション /savecred を使い、一度パスワードをWindowsの資格情報マネージャーに記録させてしまう(次回からはパスワードを聞かれることは無くなる)。
  • WScript.ShellのSendkeyを使い、パスワードとEnterを強制入力する。

後者については、さらに2通りの方法がありました。

  • RunAsの実行自体をVBScriptに埋め込んでしまい、VBScript上で自分のプロンプトにSendKeyでパスワードを打ち込む。
  • SendKeyを使うVBSCriptを別途作り、バッチでRunAsを実行する前にVBScriptを先行実行。AppActivateでrunas.exeのプロセスにSendKeyでパスワードを打ち込む。

前者については、前述のとおり、RunAsのあとにバッチ処理が続く部分の対応ができなくなるため、残念ながら却下。後者については下記のサイトに詳しく実例が書いてありましたので、そちらを参考にさせてもらって動作を試してみました。

hrkworks.com

結論は……「ほぼ上手くいった」。です。ほぼ、である理由は下記。

  • パスワード入力に失敗することがあった …… Sleepの長さなどを調整しないといけないのかもしれませんが、明確な理由に行き着くことができませんでいた。再度やりなおすと上手くいくことが多かったのですが、これだとデータベースの大事なダンプデータ取得には信頼性が足りません(せめて理由は把握しておきたい)。
  • 上記の対応で、RunAs実行後に「%errorlevel%がゼロでなければエラーログを出して終了」という処理を追加したところ、ログイン失敗後、自動的になんどもリトライするようになってしまいました(笑)。

後者、どういうこと??エラー処理はexitで処理をぶった切っているので、リトライなんて事が起きる可能性は無いと思われるのですが、実際、前述のログインできないエラーが起きたあと5回繰り返してログインできて、さらにきちんとダンプも取得出来てしまったことがありました。実際にシステムの背後で動く処理において、「なんだか判らないけれど上手くいくから大丈夫」なんてのは許されません。

魅力的な手でしたが、ちょっと不安定さが目立ったのと、ここを突き詰めている時間が無いので、資格情報マネージャーに登録する方法と併用して、初回さえ乗り切ればあとは保存したパスワードで……という路線を考えていたところ、取引先から連絡が。

処理実行ユーザーにOracleの権限を付けてみる

取引先から、過去にUNDO領域の操作でWindowsユーザーの権限が足りず、権限を追加したことがあった、との連絡がありました。結論から言うと、この権限を追加しても駄目でした(2021/10/28時点)。

ちなみにその権限グループは「ora_dba」。下記は最新版のOracle DB 19ですが、「データベース管理者用の標準Oracle Databaseグループ」として説明が書かれているので良かったら参考にしてください。

docs.oracle.com

参考情報

この件について調べる過程で参考にさせてもらったサイトのURLを記載しておきます。

Bejeweled3のプレイデータはどこにあるか(Steam版)

Steamで、もう10年以上「時間をガンガン消費して人生をロスさせる」ゲームとして我が家で君臨し続けているのは、「Bejeweled3」です。シヴィライゼーションシリーズもヤバイですが、Bejeweledの危険なところは「簡単に始められる」ということと「(理論上は)すぐにやめられる」という点ですね。

f:id:frontline:20211024121908p:plain
Bejeweled 3

このゲーム、Steamで配信しておきながらセーブデータがSteamクラウドに保管されていないようで、PCのOSを入れ直したらゲーム内での実績やハイスコアデータは全部消えます。1月にSSD導入にあわせてOSから入れ直したため、「また最初からか」と思いながらプレイしていました。しかし、古いハードディスクを処分するために必要なデータが残ってないかを漁っていて、このゲームのセーブデータと思われるデータを発見したのです!!。場所は

\Users\(User名)\AppData\Local\Steam\Bejeweled3\users\

です。この下に

  • hiscores.dat
  • users.dat

さらに、プレイヤー名のフォルダーに

  • classic.sav
  • profile.dat
  • zen.sav

があります。これでスコアや解除した実績をそのままにプレイできるようにおもいます。とりあえず上書きでファイルを配置してゲームを起動、軽くプレイして動く事までは確認しましたので、問題無いと思います(ただし保証はできません。あくまで自己責任でやってください)。

こちらにも情報がありました。他のプラットフォームでのデータの在処も書いてあるので参考にしてください。

gaming.stackexchange.com

Bejeweled 3

Bejeweled 3

Amazon

メンター制度の試験導入で挙がってきた意見、顚末

過去の社内メッセージを見返していて、ちょっと面白い記録が出てきたのでメモしておきます。

2017年に社内で「メンター制度」をやってみようという話が挙がりました。当時いた若手(3年目ぐらいまで)数名に役員がヒアリングして、やってみてもよい、と言った男性1名について、月に2回程度の面談を通してメンタリングを行おうというもの。役員氏に聞いたところ、目的は「採用情報などにメンター制度あり、と書けるようにしたい」というww 不純な動機を聞かせて頂きましたが、まぁやってみますか……ということで私が主担当となり面談することになりました。

一応、事前に対象者の上司2名に事の経緯、事情と「メンターって何か?」ということを説明。業務とは全く関係無い立場からの意見やヒアリングを、面談等で話をしていきます、ということを伝えて了承を得ました。業務内容には踏み込まず、あくまで「推進」したり「脱線を防止」したりするもので、お手伝いやメンタルケアではない、ということも繰り返し説明しました。

さらに、自分もメンターとしてメンターをやるのは初めてだったので、下記の本を1冊読んで、関連するWebサイトなどをいくつか読み通して基本的な事柄をある程度把握して取り組みました。

結果から言うと……ある程度の成果は出せたと思います。実はその対象者は、2020年末に退職してしまうのですが、その際にも(ある程度お世辞と社交辞令はあるとしても)「あのとき話を聞いてもらえなかったらもっと早く辞めていた」という言葉を残してくれましたので……。効果はあったのだとおもいます。若手の連続退職が続いている現状については、私のメンタリングが原因ではないとおもいますのでここでは触れませんw

で、メンター活動を始めて2ヶ月ぐらいで社内からフワッと挙がってきた意見が下記のようなものでした。一応、グループウェア掲示版に「メンターって何か?」という説明は書いて、公式に実施してみてますよ、ということを周知しています。その中で「メンタルケアとメンターは違うよ」という説明も筆頭にあげていました……。

しかし、挙がってきた意見は……

  • メンタル面のケアを表立ってやるのはどうかと思う。
  • 上司をすっ飛ばして指導に口出しするのはいかがなものか。
  • 上司や先輩は信頼できないという若手の意思が表れているのではないか?

……絶句ですよね。そんなだから「若手から相談相手にもしてもらえない」んですよ。

で、その後どうなったかというと、メンター制度の活動はこの1名に対して試験的に実施しただけで終わってしまいました。一応毎回、A4で2枚程度の会話内容報告、初見や問題点などの報告書を作成して役員まで含めて回覧したりして、勝手にやったわけではなく社内の仕組みとして実施するというルールは徹底しましたが……。評価されず、効果無しとみなされたようです。

なんというか……。実際の所、結局、私がやったような、メンター的な立場で若手に接することが出来ない、と音を上げた中堅社員が多かったようです。それで「中堅」やら「ベテラン」やら、いや、「先輩」ですら名乗るのはどうかとおもいますけどね。もちろんある程度特殊なスキルや考え方は習得する必要がありますが、言っても「昔から先輩後輩、上司部下の間柄で行われていたヒアリングや指導を体系化したもの」であって、不揃いでもそれぞれのやり方で出来ていて当たり前だと思っていたのですが、そうではなかったようです。

というわけで、残念なメンタリング活動の話でした。