首页 > 解决方案 > How can I use a script to keep a remote computer from sleep mode?

问题描述

We're trying to create a script that tells a list of computers to stay awake.

I've shopped around, and decided to go with one I believe I found here, but I can't get it to work on a remote system. I tried to invoke-command before, then -filepath to the script, and specified the computer name, but it does nothing. What am I doing wrong?

function workflow-Scrollock {
  Clear-Host
  Echo "Keep-alive with Scroll Lock..."
  $WShell = New-Object -com "Wscript.Shell"
  while ($true)
  {
    $WShell.sendkeys("{CAPSLOCK}")
    Start-Sleep -Milliseconds 2000
    $WShell.sendkeys("{CAPSLOCK}")
    Start-Sleep -Seconds 2
  }
}

I want to see the remote computer turn it's capslock on and off until I reboot it or stop the script.

标签: powershellsleepsuspend

解决方案


只要您的主要目标是保持计算机处于唤醒状态(而不是闪烁 Caps Lock 键),这个对相关问题的回答应该会有所帮助。基本上,您只需要通过Add-Type一些修改将所有 C# 猛烈抨击,例如:

Add-Type -TypeDefinition @"
    using System;
    using System.Net;
    using System.Runtime.InteropServices;

    public class PowerManager {
        POWER_REQUEST_CONTEXT _PowerRequestContext;
        IntPtr _PowerRequest; // HANDLE

        // Availability Request Functions
        [DllImport("kernel32.dll")]
        static extern IntPtr PowerCreateRequest(ref POWER_REQUEST_CONTEXT Context);

        [DllImport("kernel32.dll")]
        static extern bool PowerSetRequest(IntPtr PowerRequestHandle, PowerRequestType RequestType);

        [DllImport("kernel32.dll")]
        static extern bool PowerClearRequest(IntPtr PowerRequestHandle, PowerRequestType RequestType);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true, ExactSpelling = true)]
        internal static extern int CloseHandle(IntPtr hObject);

        // Availablity Request Enumerations and Constants
        enum PowerRequestType
        {
            PowerRequestDisplayRequired = 0,
            PowerRequestSystemRequired,
            PowerRequestAwayModeRequired,
            PowerRequestMaximum
        }

        const int POWER_REQUEST_CONTEXT_VERSION = 0;
        const int POWER_REQUEST_CONTEXT_SIMPLE_STRING = 0x1;
        const int POWER_REQUEST_CONTEXT_DETAILED_STRING = 0x2;

        // Availablity Request Structure
        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        public struct POWER_REQUEST_CONTEXT
        {
            public UInt32 Version;
            public UInt32 Flags;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string SimpleReasonString;
        }

        public void EnableConstantDisplayAndPower(bool enable, string reason)
        {
            if (enable)
            {
                // Set up the diagnostic string
                _PowerRequestContext.Version = POWER_REQUEST_CONTEXT_VERSION;
                _PowerRequestContext.Flags = POWER_REQUEST_CONTEXT_SIMPLE_STRING;
                _PowerRequestContext.SimpleReasonString = reason; // your reason for changing the power settings

                // Create the request, get a handle
                _PowerRequest = PowerCreateRequest(ref _PowerRequestContext);

                // Set the request
                PowerSetRequest(_PowerRequest, PowerRequestType.PowerRequestSystemRequired);
                PowerSetRequest(_PowerRequest, PowerRequestType.PowerRequestDisplayRequired);
            }
            else
            {
                // Clear the request
                PowerClearRequest(_PowerRequest, PowerRequestType.PowerRequestSystemRequired);
                PowerClearRequest(_PowerRequest, PowerRequestType.PowerRequestDisplayRequired);

                CloseHandle(_PowerRequest);
            }
        }
    }
"@
(New-Object PowerManager).EnableConstantDisplayAndPower($true, "Keeping the computer awake")
Wait-Event

我稍微清理了它以删除一些未使用的东西并使其成为一个类,然后添加Wait-Event以使其保持运行。

现在你只需要远程执行它:

Invoke-Command -AsJob -ComputerName remotecomputer -FilePath C:\Path\To\Set-KeepAwake.ps1

您可以通过检查来证明它正在工作powercfg /requests

Invoke-Command -ComputerName remotecomputer -ScriptBlock { powercfg /requests }

哪个输出:

DISPLAY:
None.

SYSTEM:
[PROCESS] \Device\HarddiskVolume1\Windows\System32\wsmprovhost.exe
Keeping the computer awake

AWAYMODE:
None.

推荐阅读