走り書き

ちょこっとしたメモを残してく。 

Windowsにhugoをインストールして試食

メモ:# めんどくさい人向け(本番向けじゃないよ) 

1.以下から extended 版 を取をダウンロード

 hugo_extended_*_windows-amd64.zip 

github.com

参考
https://gohugo.io/installation/windows/

2.適当にフォルダを掘り、ZIP を展開して hugo.exe を置く。
3.展開したフォルダを PATH に追加

追加が終わったら「hugo version」にて確認

4.サイト作成(場所は気にしない)

 hugo new site quickstart
 cd quickstart

5.テーマを追加

 作成されたthemesにテーマサイトで公開されてるテーマを挿入
 https://github.com/alex-shpak/hugo-book
 上記からコードのところをクリックして、zipで保存。
 themesにhugo-bookとフォルダを掘り具を挿入

6.hugo.toml にテーマ指定を追加

「hugo.toml」に「theme = 'hugo-book'」を追加 

7.サーバ起動

 hugo server --buildDrafts
 エラーが出なければ成功

8.ブラウザで確認

  http://localhost:1313/

9.content に Markdown を置いて遊ぶ

 _index.mdにして保存
 保存した瞬間にブラウザが更新される

hugo-bookは3カラムでびっくりしたのと

この更新なら、後ろでpowershellとかshellで更新してもよさそう。

ADのアカウントロックを追う

今更ながら、ADを構築したので、アカウントロックを追ってみます。

追うにあたり、2パターンで確認する方法があります。

auditpolを利用した設定方法

learn.microsoft.com

で、コマンドそのものの操作は危険と言うか、それなりに習熟しないと分けわかめ。

てなことで、こちらを参考になのですが、これもクリアとか平気に使わせるので、LLMにそこらいらを安全に倒すように直してもらうか、既存の状態をバックアップして、状況に応じて、設定を施すのが良いかと。

blog.jtc-i.co.jp

ただ、こっちのコマンドは、GPOでかき消されるので、最終的にはGPOで設定する方向になるのではないのかなと。どこまで、記録させるのは、必要なのかを見極めるのか。と、言うところなのでしょう。

アカウントロック周りで、欲しいイベントIDは、次の通り。
  • 4768 / 4771
     Kerberos 認証の原因ログ
  • 4776
     NTLM 認証の原因ログ
  • 4740
     ロックアウトの結果ログ
  • 4625
     クライアント側の補助ログ
GPOにて設定する場合は、少なくとも次の通り
  • サブカテゴリ設定を強制して監査ポリシーのカテゴリ設定を上書する >有効
  • Kerberos 認証サービス >成功:任意、失敗:有効
  • 資格情報の確認    成功:任意    失敗:有効
  • ユーザー アカウント管理    成功:有効    失敗:任意
  • ログオン    成功:任意    失敗:有効

上記の内容を Domain Controllers OU にリンクする形で、監査設定に施す。

イベントログの出方としては
  • 4768
    Kerberos 認証チケット (TGT) が要求されました。
  • 4771
     Kerberos 事前認証に失敗しました。
    0x18(パスワード違い)、0x12(ロック/無効)、0x17(期限切れ)
    といった形で、失敗理由の切り分けが可。
  • 4776
     コンピューターがアカウントの資格情報の確認を試行しました。
  • 4740
     ユーザー アカウントがロックアウトされました。
    原因は乗らないけど、呼び出し元コンピューター名までは確認可
  • 4625
    アカウントがログオンに失敗しました。
    ログオン失敗の総合ログ(原因は他イベントやStatusで判別)

レポーティング

ここらをリアルタイムで見たいニーズとか、賞味30分ぐらいのまとまった数字のレポートとして見るとか、アカウントロックが発生した場合の原因箇所を見るとかになるのかと。

LLMでそれらしいpowershellを書いてもらって、メール、チャット、監視ツールに飲み込んでもらうでもよさそうです。とりあえずCSVファイルとして保存中。

 

LLM振り返り

人さまブログを要約して読んでいたら、あーちょっと書くかと。

~2024

・便利な壁打ち・検索代替期
課金しつつ「本当に毎日使うのか」と半信半疑で利用
用頻度が増加
検索代替から壁打ち用途へ移行
モデルの頻繁な更新そのものが、徐々に信頼に

 

~2025

・作業を依頼するが、丸投げじゃない期
課金して継続利用
要約・整理・壁打ちが日常化
スクリプト作成も依頼するが、2024年比で高度に盛られる
盛りが本当に必要かは疑問 〉code系ツールで担保したい
それよりも、ジョギングのパーソナルトレーナー委託という良い使い方を見つけた

 

2026~

・用途開拓期
人がやらなくてよい作業の刈り取りを主軸に用途開拓
Code系ツールでの模索
委託系の充実

Lenovo ThinkPad エッセンシャル 13/14インチ スリムトップロードケース

 ThinkPad エッセンシャル 13/14インチ スリムトップロードケースを買ってみた。

www.lenovo.com

この手のPCが収容できるバックは、13インチ想定か15インチかでサイズ感がガラッと変わる。

13インチ対応でもギリギリで入る仕様もあれば、15インチで大きすぎることも多い。回避するには、現物確認とかになるわけで、めんどくさい。

とは言いつつ、更新しないといけないわけで

ドン。写真は、即興で用意したリモコン付き。

サイズ感はこんな感じ。

PCバックとしては利用してないので、書類とか、傘、エコバックとかとか。入れたらそれなりな容量が欲しいので、用途としては、PC前提ではないのよね。

今回のこれ、高さ、奥行きともに問題なし。横幅は前のPCバックに比べると5㎝ぐらい大き目みたいなので、ワイドパネルのPC、テンキー付きとかを意識されてるのか。そんな大きさ。

そう書くと、時代とともにPCバックもサイズは変わってるのかもしれないけど、前のPCバックの値段は1万円越え、こちらは何と数千円。安い!!!。壊れたら買いなおせばよい。

ご参考になれば、これ幸い。

DP経由でつないでるスピーカーがスリープ回復時に死亡する件

問題はこれ

learn.microsoft.com

けど、Windows11は解消してるようなのですが、どうなの。

で、以下の実装で、コンパのサウンド設定を開いて閉じるスクリプトを書き直したけど、テストしたら解消٩(*´ᗜ`)ㅅ

メモとして、トリガーはロック解除時にスクリプトを実行。実行はpowershell

本体のスクリプト

設定値を設定>コンパネのサウンド設定を探してあれば終了>無ければサウンド設定を開く>閉じる。

下のコードをコピーして、適当な名前で保存

# コンパネからサウンド設定を呼び出し閉じる
# .\Reset-SoundCpl.ps1 -DelayBeforeReopenSeconds 1 -DelayBeforeFinalCloseSeconds 1

[CmdletBinding()]
param(
  [int]$DelayBeforeReopenSeconds = 1,        # 再起動までの待機秒数(既定 5)
  [int]$DelayBeforeFinalCloseSeconds = 1,    # 再起動後に閉じるまでの待機秒数(既定 3)
  [switch]$FinalClose = $true                # 既定で自動クローズ
)

function Get-SoundCplProcesses {
  Get-CimInstance Win32_Process | Where-Object {
    $_.Name -in @('rundll32.exe','control.exe') -and
    ($_.CommandLine -match '(?i)mmsys\.cpl')
  }
}

function Stop-SoundCplProcesses {
  param([Parameter(Mandatory=$true, ValueFromPipeline=$true)][object[]]$Processes)
  process {
    foreach ($p in $Processes) {
      try {
        Stop-Process -Id $p.ProcessId -Force -ErrorAction Stop
        Write-Host "Killed PID=$($p.ProcessId) Name=$($p.Name)"
      } catch {
        Write-Warning "Stop-Process failed for PID=$($p.ProcessId): $_"
      }
    }
  }
}

function Start-SoundCpl {
  $cpl = Join-Path $env:WINDIR 'System32\mmsys.cpl'
  try {
    Write-Host "Starting Sound CPL via rundll32..."
    Start-Process -FilePath (Join-Path $env:WINDIR 'System32\rundll32.exe') `
                  -ArgumentList "shell32.dll,Control_RunDLL `"$cpl`", 0" `
                  -WindowStyle Normal
  } catch {
    Write-Warning "rundll32 での起動に失敗:$_  control.exe 経由に切り替えます。"
    try {
      Start-Process -FilePath (Join-Path $env:WINDIR 'System32\control.exe') `
                    -ArgumentList "mmsys.cpl" `
                    -WindowStyle Normal
    } catch {
      throw "mmsys.cpl の起動に失敗しました:$_"
    }
  }
}

function Wait-ForNewSoundCpl {
  param([int]$TimeoutMs = 3000, [int]$IntervalMs = 200)
  $deadline = [DateTime]::UtcNow.AddMilliseconds($TimeoutMs)
  while ([DateTime]::UtcNow -lt $deadline) {
    $procs = Get-SoundCplProcesses
    if ($procs) { return $procs }
    Start-Sleep -Milliseconds $IntervalMs
  }
  return $null
}

# 1) 既存の mmsys.cpl セッションがあれば終了
$existing = Get-SoundCplProcesses
if ($existing) {
  Write-Host "Found $(($existing | Measure-Object).Count) Sound CPL process(es). Closing..."
  $existing | Stop-SoundCplProcesses
} else {
  Write-Host "No existing Sound CPL processes found."
}

# 2) 指定秒数待機
Write-Host "Waiting $DelayBeforeReopenSeconds second(s) before reopen..."
Start-Sleep -Seconds $DelayBeforeReopenSeconds

# 3) 再起動
Start-SoundCpl

# 4)(既定で有効)再度検索して一定時間後に終了
if ($FinalClose) {
  Write-Host "Waiting $DelayBeforeFinalCloseSeconds second(s) before final close..."
  Start-Sleep -Seconds $DelayBeforeFinalCloseSeconds

  $after = Wait-ForNewSoundCpl -TimeoutMs 3000 -IntervalMs 200
  if ($after) {
    Write-Host "Final close of Sound CPL..."
    $after | Stop-SoundCplProcesses
  } else {
    Write-Host "Sound CPL not found for final close (timeout)."
  }
}

 

で、これをどう起動させるのか。

www.intellilink.co.jp

こちらの記事をオマージュし、記事中のStartPs1.vbsをそのまま利用

書いてる内容をコピーして、メモ帳に張り付けて保存。

 

タスクスケジューラを起動して、新規にタスクを作成

トリガータブを開いて、タスクの開始:ワークステーションアンロック時、有効などにしてもらう。

操作タブも開いて新規にて作成し、操作:プログラムの開始、プログラム:wscript.exe。

引数は「//B "C:\apps\StartPs1.vbs" "C:\apps\sound-on.ps1"」先ほど保存したファイルにして閉じる。

画面をロックして、スリープは、PCの設定がそれ用になってないとスリープにならなさそうとか思ったけど、まあ…。

で、無事スリープが出来ましたら、解除して瞬間コンパネのサウンドがちらっと映ったらOK。

おしまい。

 

AD配下のPCイベントログを転送してみた

初見殺しだけど、ワークステーションとかでやるともっと大変なんだとか。

ベースの手順 

www.yubion.com

〇ソースマシン(転送元)

1.ソースマシンで次のコマンドを管理者権限で実行
winrm quickconfig
2.ローカルユーザーとグループ」を開き、「グループ」の「Event Log Readers」を開く
lusrmgr.msc
# オブジェクトの種類の選択で「コンピューター」を選んでください
 
3.「Event Log Readers」にコレクトと「Network Service」を追加
# Windows11の場合、場所を自分PCにして登録
# DCの場合、AD上のbuiltinにあるグループに追加、追加後「gpupdate /force」
 
4.以下のコマンドにてchannelAccessの値をコピー
wevtutil gl Security 
5.コピーした内容をもとに、「(A;;0x1;;;NS)」を末尾に追加して実行
wevtutil sl Security /ca:"O:BAG:SYD:(A;;0xf0005;;;SY)(A;;0x5;;;BA)(A;;0x1;;;S-X-X-XX-XXX)(A;;0x1;;;NS)"
 
6.プロキシ環境下は、例外設定でコレクト側PCのホスト名も追加してください
# エラー対応
netsh winhttp show proxy
inetcpl.cpl
netsh winhttp import proxy source=ie
netsh winhttp show proxy
net stop winrm
net start winrm

# 名称解決するかお手軽に確認する方法としては

# イベントビュワー(eventvwr)のサブスクリプションを新規に作成
# コレクトのPCを登録してテスト

# ソース側ではこちらの登録はしないので、確認ができたらキャンセルで逃げます
 
7.こちらはこれでおしまい
 

★コレクト(ログを収集)

1.コレクトのPCで以下のコマンドを管理者にて実行
wecutil quick-config
#問われたらYで進む
 
2.イベントビュワーを開く
eventvwr
 
3.サブスクリプションを作成し、ソースになるコンピュータを登録してテスト
# エラーになる場合は、プロキシの例外設定を確認
netsh winhttp show proxy
inetcpl.cpl
netsh winhttp import proxy source=ie
netsh winhttp show proxy
net stop winrm
net start winrm
 
# 後扱いが面倒になるので英数字のみにするとよいかと
 
5.イベントの選択をクリック
  • イベントレベルから全部選ぶ
  • ログごとから、Windowsのログの「Application,セキュリティ,システム」を選ぶ
#無事稼働が出来たら、何を集計して監視とか、そのものを監視するのか調整を
 
6.入力が完了したらOKで閉じて、次のコマンドを入力
# サブスクリプション名は、先ほど入力した名前です

7.設定はこれで以上です

 

■確認

1.転送内容を確認する

コレクトのイベントビュワーを開いて、セキュリティまで転送されてるかを確認
# コンピュータ名を追加したい場合は、タイトルのところを右クリックにて追加で

 

2.Powershellにて確認する

Get-WinEvent -LogName "ForwardedEvents" | Select-Object -First 10

# 最初の10件だけ表示する

 

〇その他

Windows Server 2012 R2、Windows Server 2016、Windows Server 2020で確認。

ADがあれば入れてよいけど、NXlogで集約してもよいのでないかとは思った。

ハードウェア、アプリを追うのか、セキュリティ追うのかは区別したほうがよい。

詳細、何が欲しいのかは、この作業とは別なので、がんばってください。

Get-MessageTraceDetailV2はどんな結果が出るの

Exchange Online のトレース画面からプロパティをポチポチ見るのも悪くないのですが、「もう PowerShell で完結」というとき用のメモです。

コマンドレットで完結すると、powershell5.1を開いて以下の内容を実行。

# コマンドレットが無ければ、こちらの手順で

Connect-ExchangeOnline

#時間はUTCで+9してください
$StartDate = [datetime]"2025-12-10 09:00"
$EndDate   = [datetime]"2025-12-11 09:00"
$Interval  = 1 # 時間単位
$Results   = @()

while ($StartDate -lt $EndDate) {
    $NextEnd = $StartDate.AddHours($Interval)
    if ($NextEnd -gt $EndDate) { $NextEnd = $EndDate }

    $Batch = Get-MessageTraceV2 -StartDate $StartDate -EndDate $NextEnd
    $Results += $Batch

    $StartDate = $NextEnd
}

$Results | Export-Csv ".\MessageTrace.csv" -Encoding UTF8 -NoTypeInformation

実行したディレクトリにファイルが出来るので開く。開くと一覧になってるので、statusを確認し、見てみたい内容の選ぶと。

statusはこんな値

  • Delivered:正常に配信
  • Expanded:配布グループの展開
  • Failed:宛先に配信NG
  • FilteredAsSpam:スパム判定
  • Quarantined:メッセージの隔離

Quarantinedなメールがあったので、こちらのコマンドレットを実行

Get-MessageTraceDetailV2 -MessageTraceId xxxxxxxxxx-xxx-xxx-xxx-xxxxxxxx -RecipientAddress hoge@hogehoge.com

 

Date                   Event                Detail
----                   -----                ------
2025/11/24 22:47:48    受信                 XXXXXXXXXXXXXXXX.XXX.OUTLOOK.COM でメッセージが受信されました。
2025/11/24 22:47:50    スパム               スパム信頼度レベル: 8
2025/11/24 22:47:51    配信                 メッセージはフォルダー DefaultFolderType:QuarantinedEmailSecured に正常...

と内容は確認できます。

LLMで上手に組み合わせたら、らしいスクリプトがかけるけど、リアルタイムに見たいのか。その前に、statusの件数を数え、増えたら詳細を得る運用でもよさそうだ。そこまで見るのかと思ったら、DMARC対策用にリストにしてもよさそうね。

あと自動化したい場合は、Entra ID にアプリとして登録して認証をパススルーしてやってください。