You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

系统账户启动的PowerShell脚本如何将NotifyIcon附加到登录用户会话

解决方案

1. 核心问题原因

系统账户运行的进程未关联到用户的交互式桌面会话,因此NotifyIcon这类UI组件无法显示在用户任务栏中。要解决这个问题,需要将通知代码注入到已登录用户的活动会话中执行。

2. 获取目标用户的会话ID

先获取已知用户的活动会话ID,用于后续在该会话中启动通知进程:

$targetUsername = "你的用户名"
# 从quser输出中提取会话ID
$sessionInfo = quser | Where-Object { $_ -match $targetUsername }
if (-not $sessionInfo) {
    Write-Host "目标用户未登录"
    exit
}
$sessionId = ($sessionInfo -split '\s+' | Select-Object -Index 2) -as [int]

3. 在用户会话中执行通知代码

使用psexec.exe(Sysinternals工具,系统账户可直接调用)在目标会话中启动PowerShell进程运行通知逻辑。先将通知代码编码为Base64避免转义问题:

备份开始通知代码块

$startNotificationScript = {
    $iconPath = "C:\icon.ico"
    try {
        $icon = New-Object System.Drawing.Icon $iconPath
        $notification = New-Object System.Windows.Forms.NotifyIcon
        $notification.Icon = $icon
        $notification.Visible = $true
        $notification.ShowBalloonTip(5000, "Burp backup started", "备份已开始,请不要关机", [System.Windows.Forms.ToolTipIcon]::Info)
        Start-Sleep -Seconds 5
        $notification.Dispose()
        $icon.Dispose()
    }
    catch {
        # 捕获错误避免进程异常退出
        Write-Error $_.Exception.Message
    }
}

# 编码脚本为Base64
$encodedStartScript = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($startNotificationScript.ToString()))

# 在目标会话中执行通知
& psexec.exe -i $sessionId -accepteula powershell.exe -EncodedCommand $encodedStartScript

备份完成通知代码块

同理,备份结束时执行:

$finishNotificationScript = {
    $iconPath = "C:\icon.ico"
    try {
        $icon = New-Object System.Drawing.Icon $iconPath
        $notification = New-Object System.Windows.Forms.NotifyIcon
        $notification.Icon = $icon
        $notification.Visible = $true
        $notification.ShowBalloonTip(5000, "Burp backup finished", "备份已完成", [System.Windows.Forms.ToolTipIcon]::Info)
        Start-Sleep -Seconds 5
        $notification.Dispose()
        $icon.Dispose()
    }
    catch {
        Write-Error $_.Exception.Message
    }
}

$encodedFinishScript = [Convert]::ToBase64String([System.Text.Encoding]::Unicode.GetBytes($finishNotificationScript.ToString()))
& psexec.exe -i $sessionId -accepteula powershell.exe -EncodedCommand $encodedFinishScript

4. 阻止备份期间关机

为避免备份过程中电脑关机,可通过API设置进程的关机优先级,让系统等待备份进程结束后再关机:

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

public class ShutdownBlocker {
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern bool SetProcessShutdownParameters(uint dwLevel, uint dwFlags);
}
"@

# 设置进程关机优先级为最高(0x00000001),阻止系统强制关机
[ShutdownBlocker]::SetProcessShutdownParameters(0x00000001, 0)

将这段代码放在备份启动命令之前即可。

注意事项

  • 确保psexec.exe已存在于系统路径中,或使用完整路径调用(如C:\Tools\psexec.exe)
  • 系统账户默认有权限调用psexec访问用户会话,无需额外凭据
  • 如果目标用户未登录,通知逻辑会自动跳过,可根据需求添加日志记录

内容的提问来源于stack exchange,提问作者n.karlen

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 11:17:09