0

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!

serlag8622
  • 25
  • 1
  • 1
  • 7

1 Answers1

0

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.

skyhammer
  • 117
  • 1
  • 7
  • Hi skyhammer! What do you mean exactly? I don't know how to fix the whole “for” block without actually breaking my whole code. I tried the parameter “/s”, but somehow my client still rebooted instead of turning off. – serlag8622 Aug 02 '23 at 14:21
  • Hi @serlag8622 - I've updated my answer with a suggested fix for the "for" block, which basically adds the necessary curly braces to make the if/else statement work. As for the shutdown, I would expect the `shutdown /s /t 1` to work; it did work on my test PC, so is there some other setting, perhaps in the BIOS, that may prevent a full shutdown from happening and will power the PC back on? – skyhammer Aug 02 '23 at 22:46
  • hi @skyhammer! I tried running the script and modified the if block to "if ($Idle.Hours -eq "0")" instead of three hours and it works! My PC completely shuts down. But unfortunally, if I run it though our deployment software, it won't work. Maybe PDQ doesn't have enough permission to run a powershell script? – serlag8622 Aug 03 '23 at 10:12
  • Hi @serlag8622 - Glad that at least part of this issue has been resolved. I'm afraid I don't have any experience with PDQ. Has the execution policy been configured on your clients to allow scripts to run? I saw [this](https://www.pdq.com/blog/writing-your-first-powershell-script/) article on PDQ's website, so not sure if it's applicable. You may also want to try to debug using some "write-output" statements in the code to see which `if/else` block is being used. For example, if the `else` block is processed, you won't see anything anyway with the `out-null` statement. – skyhammer Aug 03 '23 at 17:55