パソコン練習日記

やってみたことを記録しています。Bloggerからこちらに引っ越して来ました。一部、画像がリンク切れしていますがひとつひとつ直すのは心が折れたのでそのままにします。

長年使っているMicrosoftアカウントが「このMicrosoftアカウントは存在していません。」て出てビビったけど数時間で復旧

朝、MicrosoftアカウントでSSOしているChatGPTへログインするため認証を行ったところ、認証失敗と出た。

なんか間違えたかな?と思いながらもう一度認証すると、

「このMicrosoftアカウントは存在していません。」

メールアドレス入力し間違えたかな?と思ってやり直したり、スペルチェック?したりしたけど

あってんだよなぁ。。

 

別のデバイスから入ってみよう。と、やったけど、やっぱりダメ。

 

障害かなぁ?と思いながら、"Microsoftアカウント 障害"とかで検索したけど、Microsoft365の障害情報ページしか見当たらない。だし、いちおうMicrosoft365も障害では無さげ。

次にX(Twitter)見たけど、リアルタイムで同じ事象にあっている感じの人が誰もいない。

 

え、マジでアカウント消えた?

え、ChatGPTってMicrosoftアカウントでのSSOでしかログインできんのに、解約もできんじゃん。

10年くらい使ってるんだけど。そこそこ大事なメールとかあるし、Microsoft資格もこのアカウントに紐づいているんだけど。

とか、二要素のメール認証、このMicrosoftアカウントのメールにしてるサービス、結構あるのにログインできなくなるじゃん。全部サポートに連絡したりして、復旧させるの?コレ。

 

え、うそでしょ

マジでめんどくさい。うそでしょ

 

すでにセッションが確立しているiPhoneやPCからメールなどは見れるし操作できることを確認。

アカウントはまだ存在するっぽい。切れそうな細い紐だけどアクセスできる手段は確保。

とはいえ、コレも今のセッションが切れるとアクセスできなくなって終わり。ってなったらヤバイ。ぜんぜん安心できない。

 

X(Twitter)で、「よくある。次の日には復旧してる」みたいなものがあったけど、仕事で移動中もずっと「マジかよ。ほんとうに消えてたらどうしよう。」とモヤモヤ。

 

で、2時間後にスマホで認証してみたら、普通にログインできた。

障害かよ。マジで障害情報どっかに出してくれよ。いや、マジで

 

とはいえ、SSOとか2要素にメールアドレス指定しているものは、見直したほうがいいわ。コレ

 

Logicoolのハンコン G29の値をC#で取得

やりたいことがあるので、ハンコンのアクセル開度やハンドルの値をC#で取得したいのです。

 

 

ということで

ちゃんと取得できるようになるまでの記録です。

実際に動いたプログラムはここに置いています。

github.com

 

まずは、ChatGPTにサンプル作ってとお願い。

「とりあえずハンドル角度とアクセル開度取得のプログラムお願いします。」

で、もらったのが以下。

ちなみにSharpDX.DirectInputをNuGetでインストールが必要。

using System;
using SharpDX.DirectInput;

class Program
{
    static void Main()
    {
        // DirectInputインスタンスを作成
        var directInput = new DirectInput();

        // 接続されているすべてのジョイスティックを取得
        var joystickGuids = directInput.GetDevices(DeviceType.Joystick, DeviceEnumerationFlags.AllDevices);
        Joystick joystick = null;

        // G29を検索
        foreach (var guid in joystickGuids)
        {
            var deviceInstance = directInput.GetDeviceDescriptor(guid.InstanceGuid);
            if (deviceInstance.ProductName.Contains("G29"))
            {
                joystick = new Joystick(directInput, guid.InstanceGuid);
                break;
            }
        }

        if (joystick == null)
        {
            Console.WriteLine("G29が見つかりませんでした。");
            return;
        }

        joystick.Acquire();

        while (true)
        {
            joystick.Poll();
            var joystickState = joystick.GetCurrentState();

            // ハンドルの角度 (通常はX軸)
            int wheelPosition = joystickState.X;

            // アクセルの開度 (通常は1つ目のスライダー)
            int acceleratorPosition = joystickState.Sliders[0];

            Console.WriteLine($"Wheel: {wheelPosition}, Accelerator: {acceleratorPosition}");
        }
    }
}

 

G29の検索する処理までちゃんと入っている。

素晴らしい。これは、一撃で終わるんじゃないか?と思いきやエラー。

 

エラー    CS1061    'DirectInput' に 'GetDeviceDescriptor' の定義が含まれておらず、型 'DirectInput' の最初の引数を受け付けるアクセス可能な拡張メソッド 'GetDeviceDescriptor' が見つかりませんでした。using ディレクティブまたはアセンブリ参照が不足していないことを確認してください    logicoolG29    E:\work\logicoolG29\logicoolG29\Program.cs    18    アクティブ

 

エラーを伝えると修正を教えてくれる。

foreach (var deviceInstance in directInput.GetDevices(DeviceType.Joystick, DeviceEnumerationFlags.AllDevices))
{
    if (deviceInstance.ProductName.Contains("G29"))
    {
        joystick = new Joystick(directInput, deviceInstance.InstanceGuid);
        break;
    }
}

 

接続しているのに見つからんかった。

 

ChatGPTに相談したら

G29は実際にはDeviceType.JoystickよりもDeviceType.DrivingやDeviceType.Gamepadとして認識されることがあります。

ってことで、修正を作ってくれる。何回かやり取りして以下の修正案

class Program
{
    static void Main()
    {
        // ...

        var joystick = FindG29(directInput);

        if (joystick == null)
        {
            Console.WriteLine("G29が見つかりませんでした。");
            return;
        }

        // ...
    }

    static Joystick? FindG29(DirectInput directInput)  // static を追加
    {
        foreach (var deviceType in new { DeviceType.Driving, DeviceType.Gamepad, DeviceType.Joystick })
        {
            foreach (var deviceInstance in directInput.GetDevices(deviceType, DeviceEnumerationFlags.AllDevices))
            {
                if (deviceInstance.ProductName.Contains("G29"))
                {
                    return new Joystick(directInput, deviceInstance.InstanceGuid);
                }
            }
        }
        return null;
    }
}

 

取れた。と思ったけど、
アクセルの値は、実はクラッチの値。

ステアリングはあってる。

 

 

色々試したいので、ブレーキとクラッチも追加

// ハンドルの角度 (通常はX軸)
int wheelPosition = joystickState.X;

// アクセルの開度
int acceleratorPosition = joystickState.Sliders[0];

// ブレーキの開度
int brakePosition = joystickState.Sliders[1];

// クラッチの開度 (RotationZを使用)
int clutchPosition = joystickState.RotationZ;

Console.WriteLine($"Wheel: {wheelPosition}, Accelerator: {acceleratorPosition}, Brake: {brakePosition}, Clutch: {clutchPosition}");

クラッチのところがブレーキ。アクセルのところがクラッチがとれているのはいいとして、アクセルの値が取れていない。

 

まぁ、でもどうせアクセルだから

AccelerationXとか、AccelerationYとかAcceleration系の値のどれかが正解だろ?

と思いながら

// アクセルの開度
int acceleratorPosition =

に入るものを変えて見ていったけど、ぜんぜん正解にたどり着かない。

 

やり方を変えて見る。

ブレークポイントおいて、変数の中を見てみる。

 

これを見て、アクセルだけオンとオフの状態を比較すれば、それだろ。と

 

で、これがアクセルオフ

{X: 32864, Y: 65535, Z: 0, RotationX: 0, RotationY: 0, RotationZ: 65535, Sliders: 65535;0, PointOfViewControllers: -1;-1;-1;-1, Buttons: False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False, VelocityX: 0, VelocityY: 0, VelocityZ: 0, AngularVelocityX: 0, AngularVelocityY: 0, AngularVelocityZ: 0, VelocitySliders: 0;0, AccelerationX: 0, AccelerationY: 0, AccelerationZ: 0, AngularAccelerationX: 0, AngularAccelerationY: 0, AngularAccelerationZ: 0, AccelerationSliders: 0;0, ForceX: 0, ForceY: 0, ForceZ: 0, TorqueX: 0, TorqueY: 0, TorqueZ: 0, ForceSliders: 0;0}

 

これがアクセルオン

{X: 32864, Y: 0, Z: 0, RotationX: 0, RotationY: 0, RotationZ: 65535, Sliders: 65535;0, PointOfViewControllers: -1;-1;-1;-1, Buttons: False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False;False, VelocityX: 0, VelocityY: 0, VelocityZ: 0, AngularVelocityX: 0, AngularVelocityY: 0, AngularVelocityZ: 0, VelocitySliders: 0;0, AccelerationX: 0, AccelerationY: 0, AccelerationZ: 0, AngularAccelerationX: 0, AngularAccelerationY: 0, AngularAccelerationZ: 0, AccelerationSliders: 0;0, ForceX: 0, ForceY: 0, ForceZ: 0, TorqueX: 0, TorqueY: 0, TorqueZ: 0, ForceSliders: 0;0}

 

Yが変わってる。Yじゃね?

ってことで修正。

using System;
using SharpDX.DirectInput;

class Program
{
    static void Main()
    {
        // DirectInputのインスタンスを作成
        var directInput = new DirectInput();

        // 接続されているすべてのジョイスティックを取得
        var joystickGuids = directInput.GetDevices(DeviceType.Joystick, DeviceEnumerationFlags.AllDevices);
        var joystick = FindG29(directInput);

        if (joystick == null)
        {
            Console.WriteLine("G29が見つかりませんでした。");
            return;
        }

        joystick.Acquire();

        while (true)
        {
            joystick.Poll();
            var joystickState = joystick.GetCurrentState();

            // ハンドルの角度 (通常はX軸)
            int wheelPosition = joystickState.X;

            // アクセルの開度 (通常はY軸)
            int acceleratorPosition = joystickState.Y;

            // クラッチの開度 (RotationZを使用する場合)
            int clutchPosition = joystickState.Sliders[0];

            // ブレーキの開度
            int brakePosition = joystickState.RotationZ;

            Console.WriteLine($"Wheel: {wheelPosition}, Accelerator: {acceleratorPosition}, Brake: {brakePosition}, Clutch: {clutchPosition}");
        }
    }

    static Joystick? FindG29(DirectInput directInput)  // static を追加
    {
        foreach (var deviceType in new { DeviceType.Driving, DeviceType.Gamepad, DeviceType.Joystick })
        {
            foreach (var deviceInstance in directInput.GetDevices(deviceType, DeviceEnumerationFlags.AllDevices))
            {
                if (deviceInstance.ProductName.Contains("G29"))
                {
                    return new Joystick(directInput, deviceInstance.InstanceGuid);
                }
            }
        }
        return null;
    }
}

 

で、実行。

ちなみに、Gifにしているからカクカクしているけど、

実際は、0.001秒に30回ほど値を取得して表示している。

 

これでとりあえず、C#でG29の値が取れることはわかったので、

次に進もうと思う。

 

[blog:g:4207112889945342980:banner][blog:g:11696248318754550877:banner][blog:g:11696248318754550880:banner]

AnsibleプレイブックでWindowsServerの日本語化

WindowsServerの日本語化のAnsibleプレイブックを作ったので、Githubに置きました。

ansible/configure_windows_lang_jp at master · aki-sfarm/ansible (github.com)

 

 

Azure側で提供されているWindowsServerイメージを利用すると英語設定なので、

新しく作るたびに日本語化を自動化自体は、前からチャレンジしたりしてました。

blog.sfarm.okinawa.jp

 

そして、Ansibleプレイブックでやってみたいなとは思っていました。

Ansible勉強したいな。使ってみたいな。

でも全然勉強しない、が続いていました。が、

今回、やっとやってみました。

 

まずは、とてもお世話になった以下の記事内のスクリプトをAnsibleプレイブック化しました。ちょっとアレンジした気がしますが

www.intellilink.co.jp

 

それがconfigure_windows_lang_jp_autologon.ymlです。

使ってみた感じ、ローカルのWindowsServerを日本語化するには便利だなと思う反面、ローカルだったら最初から日本語で入れてるわ。と

で、Azure上のWindowsServerだと上の記事で紹介されているRunPowerShellScriptを使ったほうが全然良い気がする。

 

そして、PowerShellスクリプトを作成してオートログオンでRunOnceで実行させる箇所があるのですが、それやるとAnsibleでやる意味が薄れるので作ったのが、

configure_windows_lang_jp_wait.ymlです。

2回再起動が必要なのですがそこもすべてAnsibleプレイブックでやっています。

処理を並べて書いているだけですが

 

ちょっとですが、

Ansibleちゃんと使ってる感が出ました。

 

 

AnsibleからWindowsへ接続できるまでの記録

ActiveDirectoryたてたり、言語が英語のを日本語化したり、Ansibleで自動化してみたいのはいろいろありまして、

Ansibleを学習することに。

しかし、最初の段階、接続するまででそこそこしんどかった

 

ちなみにWinRM設定は何もしていない状態。

OSインストールしてからそのまま。

WindowsServerの2016も2019も、WinRMは最初から有効だった。

公式のWindows ホストのセットアップのページとかあるけど

そんなのやってない。

githubにあるConfigureRemotingForAnsible.ps1を実行とか紹介されているけど、

そんなファイル無いし。404 Not Foundなんだし。

 

ということでWinRM設定はそのままで行く感じ。

まずは、インベントリファイルを作成。

よくわからんので、まずはこんな感じにして

192.168.10.122

[windows:vars]
ansible_user=Administrator
ansible_password=
ansible_connection=winrm
ansible_winrm_transport=basic
ansible_winrm_server_cert_validation=ignore

 

win_pingを実行

192.168.10.122 | UNREACHABLE! => {
    "changed": false,
    "msg": "basic: HTTPSConnectionPool(host='192.168.10.122', port=5986): Max retries exceeded with url: /wsman (Caused by ConnectTimeoutError(<urllib3.connection.HTTPSConnection object at 0x7f64caba0f40>, 'Connection to 192.168.10.122 timed out. (connect timeout=30)'))",
    "unreachable": true
}

 

なんかHTTPSで接続しにいっているっぽい。

WinRMにHTTPS使うのって、証明書必要じゃなかったっけ?

とりあえずWindows側を確認。

winrm enumerate winrm/config/Listener

HTTPで受付している。

HTTPSにするのは、証明書作ったりめんどくさそうなので、とりあえずHTTPでいいや。

なんやかんや調べて、ansible_winrm_transportをhttpにしてみる。

192.168.10.122

[windows:vars]
ansible_user=Administrator
ansible_password=
ansible_connection=winrm
ansible_winrm_transport=http
ansible_winrm_server_cert_validation=ignore

 

192.168.10.122 | FAILED! => {
    "msg": "The installed version of WinRM does not support transport(s) ['http']"
}
とりあえずhttpにはなったっぽい。

が、WinRMがHttpをサポートしていないって言っている。

 

はぁ?さっき、Httpで受け付けているの確認したんだけど?

 

念のため、ほかのWindowsServerからwinrsでhttp接続し、ipconfig

winrs -r:http://192.168.10.150:5985/wsman -u:Administrator -p:パスワード ipconfig

ふつうに返ってくる。

つまりhttpで問題ない。おかしいのはAnsible側。

でも、"The installed version of WinRM does not support transport(s) ['http']"を検索してもそんなにヒットしない。

みんなこんなところで躓いていないってこと?

 

ansible_winrm_transportをbasicに
ansible_winrm_scheme=httpを追加。

192.168.10.122

[windows:vars]
ansible_user=Administrator
ansible_password=
ansible_connection=winrm
ansible_winrm_transport=basic
ansible_winrm_scheme=http
ansible_winrm_server_cert_validation=ignore

 

192.168.10.122 | UNREACHABLE! => {
    "changed": false,
    "msg": "basic: HTTPConnectionPool(host='192.168.10.122', port=5986): Max retries exceeded with url: /wsman (Caused by ConnectTimeoutError(<urllib3.connection.HTTPConnection object at 0x7fa624b84f40>, 'Connection to 192.168.10.122 timed out. (connect timeout=30)'))",
    "unreachable": true
}

まぁ、ダメか。くらいに思っていたけど、よく見てみるとhttpで、httpsの5986番ポートに接続に行ってる。httpは5985番ポート。

 

5985番ポートへ行ってもらうためにansible_port=5985を追加。

192.168.10.122

[windows:vars]
ansible_user=Administrator
ansible_password=
ansible_connection=winrm
ansible_winrm_transport=basic
ansible_winrm_scheme=http
ansible_port=5985
ansible_winrm_server_cert_validation=ignore

 

192.168.10.122 | UNREACHABLE! => {
    "changed": false,
    "msg": "basic: the specified credentials were rejected by the server",
    "unreachable": true
}

エラーが変わった。basicはダメっぽい。

basicって何や、って調べたらそのまんまbasic認証( ユーザー名とパスワードがBase64で送信するやつ)だった。

WindowsServer側でwinrmの設定を確認

winrm get winrm/config/service

 

Basicはfalseですね。いちおう、試しにBasic有効にしてみる。

winrm set winrm/config/service/auth '@{Basic="true"}'

 

で、再実行。

192.168.10.122 | UNREACHABLE! => {
    "changed": false,
    "msg": "basic: the specified credentials were rejected by the server",
    "unreachable": true
}

なんでだよ。

 

よくよく調べてみると、AllowUnencryptedがfalseだからダメっぽい。

 

AllowUnencryptedをtrueに変更。

winrm set winrm/config/service '@{AllowUnencrypted="true"}'

 

いったー

 

でも、もう少しだけセキュアに。

もう一度、AllowUnencryptedとAuthのBasicをfalseに戻す。

 

念のため、失敗するか確認

OK。戻った。

 

そして、インベントリを変更。
ansible_winrm_transportをntlm認証に

192.168.10.122

[windows:vars]
ansible_user=Administrator
ansible_password=
ansible_connection=winrm
ansible_winrm_transport=ntlm
ansible_winrm_scheme=http
ansible_port=5985
ansible_winrm_server_cert_validation=ignore

 

うまくいった。

winrmの設定を変更するのではなく、

こっちが正解かな。

 

10Gスイッチ(TPLINK TL-ST1008F)をヤフオクで購入したので動作確認

 ヤフオクでTPLINKのTL-ST1008Fを購入しました。
8つのSFP+ポートのやつです。

時々、未使用品が12,000円~くらいで出品されているのを見てるのですが、
今回購入したのは、中古。

しかし、10GのSFP+トランシーバーが3つ付いてくる。
中古だとしても、これだけで6,000円はするだろうと。

 

TPLINK TL-ST1008F
SFP+ポートが6つ以上のスイッチが欲しかったってのもあり
12,000円くらいで買えたらいいなぁ、と思いながら
入札。
 
競り負けているので、送料込みで15,000までならと
ちょびちょび入札。
 
結局、送料込みで15,000円くらいでした。
 
初期不良は1週間以内なら返品できるとのことなので動作チェック
 
SFPのスイッチとか初めて触るわ
 
WindowsServerの1号機と2号機をスイッチに接続。

 
iperfを実行。
スイッチの1番と2番ポートの確認。
9Gbitsないくらい。ちゃんと動く。

続いて、
3番と4番ポートに付け替えて、
これも問題なし。

次は
5番と6番ポート。
問題なし。

最後に
7番と8番ポート。
これも問題なしで、不良無し。

ちなみにiperfしているときの瞬間消費電力は5w。
10Gにしては低いんじゃないかコレ

次にSFP+トランシーバーの初期不良チェック

SFP+トランシーバーも初めて触る。
 
トランシーバーをスイッチに取り付けて
インターネットルーターとWindowsServerの1号機と2号機のLANケーブルを取り付け

WindowsServerの1号機と2号機からインターネットに接続できたので
これも動作確認OK
 
ちなみにSFP+トランシーバーつけるとボチボチ発熱する
 
消費電力もこんな感じ。
大した通信していない接続しているだけの状態で
さっきの倍以上。

ハードディスクををヤフオクで購入したので初期不良チェック

ヤフオクでハードディスクを購入しました。

2.5インチの東芝製3TBハードディスクです。


購入した理由はコレですが、
中古だけどあまり使用されてないのでポチりました。

で、
ヤフオクの商品紹介ページに
CrystalDiskInfoによるハードディスクの状態が画像で乗っているのですが
ほんとに一致するのか見てみようと思いました。

まず一つ目。
こちらはヤフオクの商品ページでは電源投入回数が7回、使用時間が25時間でした。

ハードディスクを接続してCrystalDiskInfoで見てみると
完全に一致してます。ちゃんと管理している良い出品者ですね
CrystalDiskInfo HDD1


もう一つのほうはもうちょい使われていて
商品紹介ページでの電源投入回数が157回、使用時間が162時間。
それでも
このくらいなら新古といっていいんじゃないかという感じ

こちらもCrystalDiskInfoで確認
ばっちりそのまんま
CrystalDiskInfo HDD2


ちなみにデータ消去済みとのことで
きれいにデータが消去されているか
FTK Imagerで中身を見てみることに

とりあえずHDDのオフセット0から軽くなめてみる
FTK Imager hdd1

すべて0になっていて完全消去されているっぽい

最初から最後のオフセットまで流してみる

FTK Imager hdd2

さらっと流しているが、
すべて0で上書きされているっぽい

初期化(0埋め)しても完全にきれいにすべて0には成り難いと聞いたことあるけど
何回か0で上書きしてんのかな?

今度、時間があるときやってみよっと


ポータブルなRAID1の3TBハードディスクを作ろうとしたけどダメだった




うちの検証環境はネットワークを分けていたり、初期化して環境が変わったりするので 
NASのようにネットワークを使うのは逆にめんどくさかったりします。
あと、使わないときは電源をOFFにするので、そうするとONにするのもめんどくさい。


それに
USBメモリやポータブルHDDのほうがデータを移動しやすいし、
ネットワーク経由よりも転送速度も速いわけです。


結局10回も電源いれていないNAS(RAID1)

結局使い続けているUSB系のやつ


データ移動し易く、かつ、RAID1は欲しい
で、前からウォッチしてて安くなったときに買ったのがコレ



2.5インチのHDDやSSDが2つ入る。

そして、RAID0やRAID1が組める。


PCへの接続はWAVLINKの
外部電源ありのSATA-USB変換アダプタがあるので
これで問題なし


あとは、ハードディスクを買えばいいけど
今、1.5TBほどデータがあり
2TBではそのうち足りなくなりそうなので
3TB以上にしようと。

Amazonで探していたけど
3TB以上の大容量な2.5インチのハードディスクがそんなに存在しないことを知る。

なので、そこそこ高い。
3.5インチの倍くらいしている気がする。
高い。。

やんわりヤフオクの中古見てみると
電源投入回数が10回未満、使用時間も30時間未満とかが7,000円くらいである。

それならこれでもいいかな?と思い、2つ落札。

開けてみると
なんかデカくね?

500GB(左)と比べると高さが倍以上ある。

もちろんケースには干渉して入らない


2.5インチのHDDにそんなやつあるんだ。
いま知ったわ

もちろん、ヤフオクの説明(というか商品名のところにも)には"15mm厚"って書いていました。

そんなん、意識してなかったから見てなかったわ

ケースのカバーを上下とも外せば行けると思うけど
防御力がだた下がる。

で、今
どうしようかなコレっていう状態