Thursday, June 27, 2019

Clear IE Data if the user is inactive


This script asks the user if they are active and if they say no or leave it for 30 seconds the script then clears IE data.

$logpath = "$env:systemdrive\temp\"

$date = Get-Date
Add-Content $logpath\IdleTimer.log "Strarting Script - $date"

#set the volume to 90% and unmute
Add-Type -TypeDefinition @'
using System.Runtime.InteropServices;
[Guid("5CDF2C82-841E-4546-9722-0CF74078229A"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IAudioEndpointVolume
{
    // f(), g(), ... are unused COM method slots. Define these if you care
    int f(); int g(); int h(); int i();
    int SetMasterVolumeLevelScalar(float fLevel, System.Guid pguidEventContext);
    int j();
    int GetMasterVolumeLevelScalar(out float pfLevel);
    int k(); int l(); int m(); int n();
    int SetMute([MarshalAs(UnmanagedType.Bool)] bool bMute, System.Guid pguidEventContext);
    int GetMute(out bool pbMute);
}
[Guid("D666063F-1587-4E43-81F1-B948E807363F"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDevice
{
    int Activate(ref System.Guid id, int clsCtx, int activationParams, out IAudioEndpointVolume aev);
}
[Guid("A95664D2-9614-4F35-A746-DE8DB63617E6"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
interface IMMDeviceEnumerator
{
    int f(); // Unused
    int GetDefaultAudioEndpoint(int dataFlow, int role, out IMMDevice endpoint);
}
[ComImport, Guid("BCDE0395-E52F-467C-8E3D-C4579291692E")] class MMDeviceEnumeratorComObject { }
public class Audio
{
    static IAudioEndpointVolume Vol()
    {
        var enumerator = new MMDeviceEnumeratorComObject() as IMMDeviceEnumerator;
        IMMDevice dev = null;
        Marshal.ThrowExceptionForHR(enumerator.GetDefaultAudioEndpoint(/*eRender*/ 0, /*eMultimedia*/ 1, out dev));
        IAudioEndpointVolume epv = null;
        var epvid = typeof(IAudioEndpointVolume).GUID;
        Marshal.ThrowExceptionForHR(dev.Activate(ref epvid, /*CLSCTX_ALL*/ 23, 0, out epv));
        return epv;
    }
    public static float Volume
    {
        get { float v = -1; Marshal.ThrowExceptionForHR(Vol().GetMasterVolumeLevelScalar(out v)); return v; }
        set { Marshal.ThrowExceptionForHR(Vol().SetMasterVolumeLevelScalar(value, System.Guid.Empty)); }
    }
    public static bool Mute
    {
        get { bool mute; Marshal.ThrowExceptionForHR(Vol().GetMute(out mute)); return mute; }
        set { Marshal.ThrowExceptionForHR(Vol().SetMute(value, System.Guid.Empty)); }
    }
}
'@
Try{
[audio]::Mute = $false
[audio]::Volume  = 0.9
}Catch{
    $date = Get-Date
    Add-Content $logpath\IdleTimer.log "Could not turn up the volume - $date"
}

#Some code I don't understand to get last user input time
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;
                }
            }
        }
    }
'@

<#loop indefinitely to check how long it's been for user input every 2 minutes.
If the user hasn't touched the mouse or keyboard for longer than 2 minutes we pop up a window.
If the user doesn't interact with the window in 30 seconds it self closes and clears IE
If the user click Yes it just starts over.
#>
While($true){
    $date = Get-Date
    Write-Host ("Last input " + [PInvoke.Win32.UserInput]::LastInput)
    Write-Host ("Idle for " + [PInvoke.Win32.UserInput]::IdleTime)
    Start-Sleep -Seconds 120
    $idleTime = [PInvoke.Win32.UserInput]::IdleTime
    [int64]$MINidleTimeINT = $idleTime.Minutes
    Add-Content $logpath\IdleTimer.log "User is inactive for $MINidleTimeINT seconds"

    [int64]$FileSize = "{0:N2}" -f ((Get-ChildItem C:\temp\IdleTracker.Log -Recurse | Measure-Object -Property Length -Sum -ErrorAction Stop).Sum / 1MB)

    If($FileSize -ge 1){Remove-Item $logpath\IdleTimer.log}

    If($MINidleTimeINT -ge 2){
        [console]::beep(2000,500)
        $sh = New-Object -ComObject "Wscript.Shell"
        $intButton = $sh.Popup("Are you still there?",30,"Idle Timer",4)
            If($intButton -eq 6){
                Write-Host "user is still active"
                Add-Content $logpath\IdleTimer.log "User is active - $date"
                }else{
                    Write-host "User is inactive"
                    Add-Content $logpath\IdleTimer.log "User is inactive - Clearing Cache"
                    RunDll32.exe InetCpl.cpl, ClearMyTracksByProcess 255}
}
}

No comments:

Post a Comment