本文介绍了从任务计划程序运行的 PowerShell 脚本中的 Msgbox 不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个 PowerShell 脚本,用于创建计划任务以启动脚本.这个想法是脚本中有一些需要重新启动的任务.在 PowerShell 的末尾,一个消息框应提示用户让用户知道所有任务都已完成.我究竟做错了什么?

I have a PowerShell script that creates a schedule task to launch the script. The idea is there are some task in the script that requires reboot. At the end of the PowerShell a message box should prompt the user to let the user knows that all the tasks are completed. What am i doing wrong?

Add-Type -AssemblyName PresentationFramework

TaskName = "Run Agents Install Script"
$TaskDescription = "Run Agents Install Script at logon"
$Action = New-ScheduledTaskAction -Execute 'Powershell.exe' `
  -Argument "-executionpolicy remotesigned -File $PSScriptRoot\AgentInstall.ps1"
$Trigger =  New-ScheduledTaskTrigger -AtLogOn

Register-ScheduledTask -Action $Action -Trigger $Trigger -TaskName $TaskName -Description $TaskDescription -User "System"


$MsgBoxInput =  [System.Windows.MessageBox]::Show('Installation completed successfully.','Agent Install','OK')
Switch  ($MsgBoxInput) {
    'OK'
   {

$MsgBoxInput =  [System.Windows.MessageBox]::Show('WARNING! Please install Imprivata agent manually if applicable.','Agent Install','OK')
   }
}

推荐答案

一种选择是使用终端服务 API 向控制台发送消息.不幸的是,它是原生 API,因此您需要使用 .NET 互操作来调用它,但在这种情况下它并不太棘手:

One option is to use the Terminal Services API to send a message to the console. Unfortunately, it is native API, so you need to use .NET interop to call it, but in this case it isn't too tricky:

$typeDefinition = @"
using System;
using System.Runtime.InteropServices;

public class WTSMessage {
    [DllImport("wtsapi32.dll", SetLastError = true)]
    public static extern bool WTSSendMessage(
        IntPtr hServer,
        [MarshalAs(UnmanagedType.I4)] int SessionId,
        String pTitle,
        [MarshalAs(UnmanagedType.U4)] int TitleLength,
        String pMessage,
        [MarshalAs(UnmanagedType.U4)] int MessageLength,
        [MarshalAs(UnmanagedType.U4)] int Style,
        [MarshalAs(UnmanagedType.U4)] int Timeout,
        [MarshalAs(UnmanagedType.U4)] out int pResponse,
        bool bWait
     );

     static int response = 0;

     public static int SendMessage(int SessionID, String Title, String Message, int Timeout, int MessageBoxType) {
        WTSSendMessage(IntPtr.Zero, SessionID, Title, Title.Length, Message, Message.Length, MessageBoxType, Timeout, out response, true);

        return response;
     }

}
"@

Add-Type -TypeDefinition $typeDefinition

[WTSMessage]::SendMessage(1, "Message Title", "Message body", 30, 36)

这本质上是 WTSSendMessage 函数.

您需要通过诸如query之类的工具获取SessionID.此脚本可能对此有所帮助:Get-UserSession.

You will need to get the SessionID via some tool like query. This script might help with that: Get-UserSession.

这里的 TimeOut 值为 30,这意味着弹出窗口将等待 30 秒,然后返回值 '32000'.设置为0"以永远等待.

The TimeOut value here is 30, which means the pop-up will wait 30 seconds before returning with a value of '32000'. Set to '0' to wait forever.

MessageBoxType 是此处 uType 值的组合:MessageBox 函数.因此,示例中的36"是MB_YESNO"和MB_ICONQUESTION"值的组合,因此将显示带有问号图标和是"/否"按钮的消息.请注意,文档以十六进制提供值,因此您需要将它们转换.

The MessageBoxType is a combination of the values for uType here: MessageBox Function. So the '36' in the example is a combination of the values for 'MB_YESNO' and 'MB_ICONQUESTION', so will show a message with a question mark icon and 'yes'/'no' buttons. Note that the documentation gives the values in hexadecimal, so you'll need to convert them.

我将此作为以管理员身份运行的计划任务进行了测试,它能够在其他登录用户的桌面上显示一条消息.希望有帮助.

I tested this as a scheduled task running as an admin and it was able to show a message on the desktop of a different logged on user. hope it helps.

这篇关于从任务计划程序运行的 PowerShell 脚本中的 Msgbox 不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 02:22
查看更多