Powershell Script - Shutdown PC after set idle time

328 Views Asked by At

I have to write a PowerShell script that will automatically be sent every hour from 9 PM til 4 AM through deployment software. This script should find out how long the PC is idle and if the idle time is 3 hours or even more, the device shutdowns down without any warning (basically a forced shutdown). I found this script from this user: PowerShell Idle Time of Remote Machine using Win32 API GetLastInputInfo. What this script does, it's basically displaying 10 times the idle time of the device. I changed the end of the code by inserting an “If”-method. Here's my script:

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;
            }
        }
    }
}
'@


for ( $i = 0; $i -lt 10; $i++ ) {
    $Idle = [PInvoke.Win32.UserInput]::IdleTime
    if ($Idle.Hours -eq "3"){
    shutdown -r -t 1
    else
        Out-Null}
}

Unfortunately, if I deploy this script through our deployment software "PDQ", it doesn't work. It doesn't even give any errors, so I don't know why the script isn't working. I also tried running the script directly from the pc and wrote if ($Idle.Minutes -eq "0"){. Since the idle minutes are indeed 0, it automatically reboots the whole machine (instead of turning it off, tho?). Does someone know another way? Or did I miss some code in my script? I appreciate any help!

1

There are 1 best solutions below

4
On

In your for block, I see that the else block is included in your if block, so you may want to fix that. I would suggest this:

for ( $i = 0; $i -lt 10; $i++ ) {
    $Idle = [PInvoke.Win32.UserInput]::IdleTime
    if ($Idle.Hours -eq "3"){
    shutdown /s /t 1
    }
    else {
        Out-Null
    }
}

Also, if you take a look at the shutdown parameters (shutdown /?), you will notice that the -r parameter will shutdown and reboot the computer. I think that the /s parameter is what you would need.