URAMIRAIKAN

1020のなれの果て (since 2005.6.19)

無操作が一定時間継続したときにログオフするPowerShellスクリプト

 お仕事での課題対応のための試作。
 共有PCやVDIでログインしたまま環境を占有しないようにするためとかの対応ですが、サードパーティ製品の利用が許可されなかった場合や、ロックがかかって一定時間経ったらのようなステップを踏むような場合のパーツとして。

 そんなわけでWindows標準のPowerShell、OSは最近のWindows 10が対象。それ以外の環境でも動くと思うけど動作確認はしていないです。

# Parameters Param ( [Parameter(HelpMessage="Timeout minutes until logoff")][alias("Timeout","t")][ValidateRange(1,1440)][Int]$TimeoutMin = 1, [alias("Force","f")][Switch]$ForceFlag ) $ActionInt = 0 if ($ForceFlag) { $ActionInt = $ActionInt + 4 } # Modules Add-Type @' using System; using System.Diagnostics; using System.Runtime.InteropServices; namespace PInvoke.Win32 { public static class UserInput { [DllImport("user32.dll", SetLastError=false)] private static extern bool GetLastInputInfo(ref LASTINPUTINFO plii); [StructLayout(LayoutKind.Sequential)] private struct LASTINPUTINFO { public uint cbSize; public int dwTime; } public static DateTime LastInput { get { DateTime bootTime = DateTime.UtcNow.AddMilliseconds(-Environment.TickCount); DateTime lastInput = bootTime.AddMilliseconds(LastInputTicks); return lastInput; } } public static TimeSpan IdleTime { get { return DateTime.UtcNow.Subtract(LastInput); } } public static int LastInputTicks { get { LASTINPUTINFO lii = new LASTINPUTINFO(); lii.cbSize = (uint)Marshal.SizeOf(typeof(LASTINPUTINFO)); GetLastInputInfo(ref lii); return lii.dwTime; } } } } '@ # Main Routine $Timeout = [TimeSpan]::FromMinutes($TimeoutMin) $Interval = [TimeSpan]::FromMilliseconds(850) do { Start-Sleep -Milliseconds 1000 $IdleTime = [PInvoke.Win32.UserInput]::IdleTime $TimeoutPercent = ($IdleTime.TotalSeconds / $Timeout.TotalSeconds) * 100 Write-Progress -Activity "Idle Timeout until Logoff" -Status ([String][Math]::Round($IdleTime.Totalseconds, 2) + " seconds") -PercentComplete $TimeoutPercent if ($IdleTime -gt $Timeout) { Write-Host "See you again!" (Get-WmiObject -Class Win32_OperatingSystem -ComputerName .).Win32Shutdown($ActionInt) } } while ($IdleTime -gt $Interval) exit

 TimeSpanオブジェクトを作成する方法を"New-TimeSpan"にしなかった理由はミリ秒を使いたかったからです。体感時間として1秒は結構タイムラグを感じるんですよね。あと、最初に取得するアイドルタイムが"Start-Sleep"に与えた時間より短くなるので、微調整したかったというのもあります。

 実行時のオプションはタイムアウト値 (分) と強制のスイッチ。"Write-Progress"を使っているのは個人的に試してみたかっただけで意味はないです。動作確認とかで視覚的にわかりやすいくらいですね。
 実際の実行方法は、タスクスケジューラでセッション切断時やロック時をトリガーに起動するようなケースを想定しています。


            1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31          

プロフィール

1020@管理人

都内を彷徨っているインフラエンジニアとかいう雑用係。いつだって眠い…。

最近のつぶやき

@umkn1020 (05/16-22:10)
KB5013943はなんか酷いみたいですね。私も.NETアプリが動かなくなりましたが… : https://t.co/dWDPYVRYdy
@umkn1020 (05/16-19:22)
RT @DORA_0907: ヤフオクで新品のサーバーラックは初めてみた [新品未使用] 標準ラック FS100-620EN 日東工業社製 https://t.co/NqN4bkzjAg
@umkn1020 (05/16-19:19)
ついにうちの会社は来週から原則出社に戻すみたいで、在宅勤務者には嫌がらせのようなルールが…
@umkn1020 (05/15-17:18)
なんとかPC初期化しての諸々再インストールとか完了今のところシャットダウンやスリープしてもBSODにならないから大丈夫かな。
@umkn1020 (05/14-14:42)
RT @Big_5G: 楽天モバイルが0円廃止して死んだ瞬間、3社が煽ってて草 https://t.co/K3hi99JWUb

エントリーリスト

カテゴリーリスト

タグ