検証用のWindows Server仮想マシンの自動ログイン設定をregコマンドで作る
Windows Serverで環境を作っては試し、また初期状態から再度つくる、みたいなテストを繰り返していたらログインが面倒になってきました。しかしレジストリ設定を手作業でレジストリエディタで書くのもそれはそれでめんどくさいし、.reg ファイルを作って読み込ませるのも微妙にめんどくさい。
そこで reg コマンドのコピペだけですませることにしました。
以下のコマンドのパスワード部分だけを書き換えてコピペすれば設定が完了します。
reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoAdminLogon /t REG_SZ /d "1" reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultUserName /t REG_SZ /d "Administrator" reg add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v DefaultPassword /t REG_SZ /d "パスワード"
Windows向けのsudo的なコマンドをDelphiで書く
先日、こういう記事をポストしたのですが、ここで調べた内容に基づいて Delphi で sudo 的なコードを書いてみました。
やりたいことは、別のコマンドを管理者権限で実行したいだけなので、Delphi コマンドラインアプリケーションのプロジェクトを選択し、ShellExecute を 'run as' で実行するだけの簡単な実装です。
実行するコマンドとパラメータを以下のように取得して ShellExecute に渡しています。
- ParamStr(1) で実行すべきコマンド名が渡される
- ParamStr(2) - ParamStr(ParamCount) にコマンドへの引数が入る
実際の実装はこちら。
program sudo; {$APPTYPE CONSOLE} {$R *.res} uses Windows, ShellAPI, System.SysUtils; var LParamIndex: Integer; LCommand : String; LParameters: String; LCurrentDir: String; LhInstance : HWND; begin if ParamCount >= 1 then try LCommand := ParamStr(1); if ParamCount >= 2 then for LParamIndex := 2 to ParamCount do LParameters := LParameters + ParamStr(LParamIndex) + ' ' else LParameters := ''; LCurrentDir := ExtractFilePath(ParamStr(0)); LhInstance := ShellExecute( 0, 'runas', PChar(LCommand), PChar(LParameters), PChar(LCurrentDir), SW_SHOW); except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end.
Windows 向けにChocolateyでインストールできるsudoの内部実装がVBScriptだったので、代替案を探す
セキュリティポリシー等の問題でVBScriptが禁止になったのだけど、Chocolateyでインストールできるsudoは内部実装でVBScriptが使われていたので、代替案を探すことにします。
とりあえず、検索して見つかったものをいくつか列挙してみました。
できればコマンドプロンプトとPowerShellの両方で使いたいだけど、良い代替方法がいまいち見当たらない感じ。
場合によっては、自分で実装してしまうというのも一つの解決策かもしれません。あるいは BitBucket や GitHub で公開されているコードをビルドするとか。
自分が欲しい機能は管理者権限が必要なプロセスを起動させたい、というだけです。UNIX の sudo のように一般ユーザ権限のコマンドからパイプで sudo 経由で実行したコマンドに何かを渡したいという要望はありません。
そうすると、手元にある Delphi で Win32/Win64 コマンドラインアプリケーションとして作成し、ShellExecute するアプリを作ればよいような気がしてきました。
複数の画像を順番どおりにPowerPointのファイルに差し込む作業を自動化する
とある事情でキャプチャ画像を順番通りにPowerPointのスライドに差し込む必要が出たのですが、こんなのを手作業でやるのはめんどくさいのでで自動化する方法を探したところ、Ruby で PowerPoint ファイルを生成できるものを見つけました。
そこで、これを使って画像を pptx に差し込む処理を汎用的に使えるようなスクリプトにしてみました。現時点ではとりあえず動くレベルの試験実装ですが、最低限の目的は達せられました。awk が動く環境なら、Linux (Windows Subsystem for Linux), macOS, cygwin のどれでも動くはずです。
作業に必要な powerpoint gem のインストール
gem install powerpoint
でOKです。(必要に応じて su とか sudo してください)
画像一覧を標準入力から受け取って powerpoint gem で画像を差し込むスクリプトを生成する処理をつくる
とりあえずこんなふうに awk で実装してみました。ファイル名は generateImagePptx.awk
とでもつけておきます。
#!/usr/bin/awk -f BEGIN { print "#!/usr/bin/ruby" print "" print "require \"powerpoint\"" print "@deck = Powerpoint::Presentation.new" print "" } { printf "title = \"%s\"\n", $1 ; printf "image_path = \"%s\"\n", $1 ; print "@deck.add_pictorial_slide title, image_path" ; print "" } END { print "@deck.save('images.pptx')" }
これで images.pptx に対して、指定されたファイル一覧を差し込む(正確には新規作成する)処理が生成できます。
実行してみる
png形式のファイルをまるごと渡すとスクリプトが作られるので、たとえば次のように実行するとよいでしょう。
ls *.png | generateImagePptx.awk | ruby
こうすれば、生成されたスクリプトがそのまま ruby 経由で実行されます。
差し込まれる画像の順番が思ったとおりにならない場合の対処
ファイル名の命名規則によっては思った通りの順番にならないことがあります。たとえばファイル名が slide-1.png, slide-2.png のように命名されていると、ls の結果が次のようになってしまい、意図通りの順になりません。
$ ls -l *.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-1.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-10.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-2.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-3.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-4.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-5.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-6.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-7.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-8.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-9.png
画像ファイルのタイムスタンプが時系列に並んでいるならば、-tr をつけてあげれば次のように意図通りに並びます。
$ ls -ltr *.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-1.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-2.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-3.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-4.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-5.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-6.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-7.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-8.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-9.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-10.png
しかしなんらかの理由でタイムスタンプが時系列順ではない場合は、この方法では思った通りの順番で出力できません。
$ ls -ltr *.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-1.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-3.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-4.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-6.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-7.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-8.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-9.png -rw-r--r-- 1 pslabo staff 0 6 15 06:49 slide-10.png -rw-r--r-- 1 pslabo staff 0 6 15 06:50 slide-5.png -rw-r--r-- 1 pslabo staff 0 6 15 06:50 slide-2.png
この場合は sort コマンドを間に挟みつつ slide-number.png を -t -
で slide と number.png に分割し、number.png の部分を -k 2 -n
で数値順ソートすれば意図通りの順番に並べることができます。
$ ls *.png | sort -t - -k 2 -n | xargs -n 1 ls -l -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-1.png -rw-r--r-- 1 pslabo staff 0 6 15 06:50 slide-2.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-3.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-4.png -rw-r--r-- 1 pslabo staff 0 6 15 06:50 slide-5.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-6.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-7.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-8.png -rw-r--r-- 1 pslabo staff 0 6 15 06:48 slide-9.png -rw-r--r-- 1 pslabo staff 0 6 15 06:49 slide-10.png
したがって、次のように実行すればファイルのタイムスタンプによらず順番に画像を差し込んだ pptx を生成できます。
ls *.png | sort -t - -k 2 -n | generateImagePptx.awk | ruby
これでとりあえず最低限の目的は達せられていますが、ruby を別コマンドで実行しなければならない点がイマイチです。ここは print や printf の後に | "/usr/bin/ruby" をつけて awk のスクリプト内で ruby と連携したほうがよいですね。
試験用データが作成できるサービスを探してみる
できれば日本語の試験用ダミーデータを作りたいので、見つけたサービスをとりあえず列挙していきます。
人名、会社名、住所などのダミーデータを最大3000件まで作れる。出力はCSVまたはSQL。 roopidea.com
個人情報を最大5000件作れる。HTML, XML, CSV, タブ区切りで生成可能。 kazina.com
テスト用のクレジットカード番号 www.find-job.net
Windows10の仮想マシンを新規インストール後にやっておきたい設定
作業用の仮想マシンを壊してしまい、環境を作りなおそうと思ったけど、ゼロからの環境構築は、たまにしかやらないので案外めんどくさいです。
そこで、このエントリに自分の作業用環境に必要なものを一旦書き出していき、まとまったら最終的にキッティング作業用に自動化するためのスクリプト(Powershell またはバッチファイル)を作ろうと思います。
コンピュータ名を設定する
コマンドプロンプトから実行する方法。
wmic computersystem where name="%computername%" call rename name="New-PC-Name"
PowerShell から実行する方法。
Rename-Computer -NewName "New-PC-Name" -Force -Restart
仮想マシンが自動でスリープしないようにする
初期設定だと勝手にスリープして困るので、スリープしないようにします。
powercfg.exe /change standby-timeout-ac 0 powercfg.exe /change monitor-timeout-ac 0
Windows Update を実行する
(New-Object -ComObject Microsoft.Update.AutoUpdate).DetectNow()
Windows Subsystem for Linux をインストールする
bash が使えないのはつらいのでこれは普通に入れる。
Enable-WindowsOptionalFeature -Online -FeatureName Microsoft-Windows-Subsystem-Linux
あとは適当なディストリビューションを Windows Store から選んでインストールする。
(Windows10 LTSC や Windows Server だとサイドローディングになるので、それぞれ別の対応が必要なことに注意が必要)
Chocolatey をインストールする
いろいろインストールするのを自動化したいので、そのために Chocolatey を入れます。
@"%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe" -NoProfile -InputFormat None -ExecutionPolicy Bypass -Command "iex ((New-Object System.Net.WebClient).DownloadString('https://chocolatey.org/install.ps1'))" && SET "PATH=%PATH%;%ALLUSERSPROFILE%\chocolatey\bin"
参照するDNSサーバを Google Public DNS に変更する
様々な理由によりDNSサーバによる名前解決をインターネット側から見た場合の挙動に揃えたいので、DNSサーバを Google Public DNS に変更します。
netsh interface ip set dns "Ethernet0" static 8.8.8.8 primary netsh interface ip add dns "Ethernet0" 8.8.4.4
よく使うフォントをインストールする
コーディング用のフォントとかを入れます。
よく使うショートカットをつくる
Snipping Tool とか、ペイントとか、意外に使うことが多いので、ここらへんはタスクバーに予め作っておく
よく使うツールを入れる
必須でインストールするのはここらへん。
- Visual Studio Code
- Google Chrome, JSONViewer, Restlet Client
- Git for Windows または SourceTree
Firebase Cloud Messaging で node からメッセージを飛ばす
Delphi で Android 向けにリモートプッシュ通知を送信しようと思ったら GCM はオワコンで FCM が必要なのに、Delphi は FCM に正式対応していない中、とりあえずサーバでの送信側実装とクライアントでの受信側実装のプロトタイプを作っている。
クライアント側は一応動くようになったので、サーバ側の試作のために一旦 node で書いてみることにします。
ここらへんを読みながら...
https://firebase.google.com/docs/admin/setup?hl=ja https://firebase.google.com/docs/cloud-messaging/admin/send-messages?hl=ja
なんとなくノリだけで書いたコードがこちら。
var admin = require('firebase-admin'); admin.initializeApp({ credential: admin.credential.cert({ "type": "service_account", "project_id": "fcmremotepush-xxxxxxx", . . . databaseURL: 'https://fcmremotepush-xxxxxxx.firebaseio.com' }); // This registration token comes from the client FCM SDKs. var registrationToken = 'メッセージ送信対象デバイスのトークン'; // See documentation on defining a message payload. var message = { "notification":{ "title":"Portugal vs. Denmark", "body":"great match!", }, token: registrationToken }; // Send a message to the device corresponding to the provided // registration token. admin.messaging().send(message) .then((response) => { // Response is a message ID string. console.log('Successfully sent message:', response); }) .catch((error) => { console.log('Error sending message:', error); });