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/10-20:33)
明日は約1カ月ぶりに都内か
@umkn1020 (05/09-14:13)
妙に眠いが、ガッツリ昼寝してしまうとまた生活リズムが戻らなくなる
@umkn1020 (05/09-12:30)
RT @Isseki3: インドの人口 14億 アメリカの人口 3.3億 インドで1日40万人発症、アメリカと同じにすると9.4万人。アメリカのピークは30万人 インドで1日4000人死亡はアメリカなら943人。アメリカのピークは1日4500人死亡 アメリカが終わったので…
@umkn1020 (05/09-12:28)
PASMOへのチャージはオートチャージ頼みだったから、通勤がないと残額がなくなっていることに全然気づかなかった。
@umkn1020 (05/07-22:42)
最初の1回以降はずっと無視していたな~ https://t.co/tzBKgcSRUJ

エントリーリスト

カテゴリーリスト

タグ