Showing results for 
Search instead for 
Did you mean: 

Automatic Shutdown

Novitiate II

This document details the "Automatic Shutdown" project, developed using a PowerShell script running on JumpCloud. The main objective is to automate system shutdown when a computer remains idle for a specific period.

Target Audience:

  • JumpCloud administrators
  • System administrators interested in managing idle computer shutdown

Project Overview:

  • Platform: JumpCloud
  • Scripting Language: PowerShell
  • Functionality: Detects idle user activity and initiates automatic system shutdown.
  • Key Features:
    • Idle Time Detection using Win32 API
    • Configurable Timeout
    • Forced Shutdown
    • User Confirmation Prompt
    • RunAsCurrentUser Execution

Code Structure:

  1. Dependency Checks:
    • Installs NuGet and RunAsUser PowerShell module if missing.
  2. Command Block:
    • Encapsulates the core shutdown logic within a scriptblock.
  3. Idle Time Tracking:
    • Leverages PInvoke to access Win32 API's GetLastInputInfo function for accurate idle time measurement.
  4. Shutdown Threshold:
    • Sets a configurable idle threshold in seconds ($idleThreshold) to trigger shutdown.
  5. Continuous Monitoring:
    • Employs a while loop to continuously check idle time.
  6. Shutdown Initiation:
    • If idle time exceeds the threshold:
      • Initiates shutdown with a 30-second delay using shutdown.exe.
      • Displays a confirmation prompt using a WScript.Shell message box.
      • If the user confirms (clicks OK), aborts shutdown using shutdown -a.
      • If no interaction, proceeds with shutdown using Stop-Computer -Force.
  7. Execution Context:
    • Uses Invoke-AsCurrentUser to execute the scriptblock in the context of the current user, ensuring proper idle time detection.

Additional Notes:

  • Testing: Thoroughly test the script in a controlled environment before deployment.
  • Timeout Configuration: Adjust the $idleThreshold value to suit your needs.
  • Exclusions: Consider adding logic to exclude specific applications or processes from triggering shutdown.
  • JumpCloud Integration: Explore options for centralized configuration and reporting through JumpCloud policies and tools.
  • Error Handling: Implement error handling and logging for enhanced reliability.


  • Energy savings
  • Enhanced security
  • Improved resource management
  • Compliance with organizational policies


This project demonstrates the value of PowerShell automation for managing idle computer shutdown on JumpCloud. By combining idle time detection, configurable timeouts, user confirmation, and proper execution context, it provides a flexible and effective solution for optimizing resource utilization and security.

Code Highlights:

# If Nuget is not installed, go ahead and install it
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$PkgProvider = Get-PackageProvider
If ("Nuget" -notin $PkgProvider.Name){
    Install-PackageProvider -Name NuGet -Force

# If PSModule RunAsUser is not installed, install it
if ( -not (get-installedModule "RunAsUser" -ErrorAction SilentlyContinue)) {
    install-module RunAsUser -force

$Command = {
    #Powershell Command Goes Here - paste your code:

    <#  testing the accuracy of GetLastInputInfo - testing Idle Time (Done)#>

    <#  testing the accuracy of GetLastInputInfo - testing Idle Time (Done)#>

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);

        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;

# Set the idle threshold for shutdown (in seconds)
$idleThreshold = 20  # Adjust this value as needed

while ($true) {
    $idleTime = [PInvoke.Win32.UserInput]::IdleTime.TotalSeconds
    Write-Host ("Idle for: $idleTime seconds")

    if ($idleTime -ge $idleThreshold) {
        Write-Host "User is idle for $idleThreshold seconds. Initiating shutdown..."

        # Initiate shutdown with a delay
        Start-Process -FilePath "shutdown" -ArgumentList "-s -t 30" -NoNewWindow -Wait

        # Prompt the user to confirm or abort shutdown # Display message box
        $confirmation = (New-Object -ComObject WScript.Shell).Popup("If you see this and don't want to shut down the PC, just click OK.", 0, "Shutdown Cancellation", 1)

        if ($confirmation -eq 1) {
            # User clicked OK, abort shutdown
            Write-Host "Shutdown aborted by user."
            # Abort the shutdown using shutdown -a
            Start-Process -FilePath "shutdown" -ArgumentList "-a" -NoNewWindow -Wait

        } else {
            # User didn't interact, allow shutdown to proceed
            Write-Host "Shutting down..."
            # Implement your shutdown logic here
            Stop-Computer -Force

    Start-Sleep -Seconds 20  # Check every 20 seconds

# end


invoke-ascurrentuser -scriptblock $Command


Community Manager Community Manager
Community Manager

@cali thank you for taking the time to share such a detailed guide with the community! We appreciate you 🙂