如何使用脚本使远程计算机远离睡眠模式?
How can I use a script to keep a remote computer from sleep mode?
我们正在尝试创建一个脚本,告诉计算机列表保持清醒。
我四处货比三家,决定使用我相信在这里找到的一个,但我无法让它在远程系统上工作。我之前尝试过 invoke-command
,然后 -filepath
到脚本,并指定了计算机名称,但它没有任何作用。我做错了什么?
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
}
}
我想看到远程计算机打开和关闭它的大写锁定,直到我重新启动它或停止脚本。
只要您的主要目标是保持计算机处于唤醒状态(而不是闪烁 Caps Lock 键),此 answer to a related question 应该会有所帮助。基本上你只需要通过一些修改将所有 C# 转换为 Add-Type
,例如:
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
我稍微清理了一下,删除了一些不用的东西,把它变成了 class,然后添加了 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.
我们正在尝试创建一个脚本,告诉计算机列表保持清醒。
我四处货比三家,决定使用我相信在这里找到的一个,但我无法让它在远程系统上工作。我之前尝试过 invoke-command
,然后 -filepath
到脚本,并指定了计算机名称,但它没有任何作用。我做错了什么?
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
}
}
我想看到远程计算机打开和关闭它的大写锁定,直到我重新启动它或停止脚本。
只要您的主要目标是保持计算机处于唤醒状态(而不是闪烁 Caps Lock 键),此 answer to a related question 应该会有所帮助。基本上你只需要通过一些修改将所有 C# 转换为 Add-Type
,例如:
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
我稍微清理了一下,删除了一些不用的东西,把它变成了 class,然后添加了 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.