如何向服务器所有用户推送PowerShell弹窗消息?
向服务器所有用户推送弹窗消息的两种实现方法
方法一:直接推送New-WPFMessageBox命令到所有用户会话
要将指定的WPF弹窗命令推送给服务器上所有已连接用户,需结合会话管理工具在每个用户的桌面会话中执行命令,步骤如下:
获取所有活跃用户会话
使用PowerShell获取当前登录用户的会话ID:# 获取交互式登录(本地/远程桌面)的用户会话ID $sessionIds = Get-CimInstance Win32_LogonSession | Where-Object { $_.LogonType -in 2,10 } | ForEach-Object { (Get-CimAssociatedInstance $_ -ResultClassName Win32_LogonSession).SessionId } | Select-Object -Unique在目标会话中执行弹窗命令
借助psexec工具(需提前安装),在指定会话的STA模式下执行弹窗命令:foreach ($id in $sessionIds) { psexec.exe -i $id powershell.exe -sta -Command @" # 确保New-WPFMessageBox函数已定义(若未全局可用,需在此处粘贴函数代码) New-WPFMessageBox -Content `$StackPanel -Title 'Commit ID:$($env:build_sourceversion)' -TitleBackground LightSeaGreen -TitleTextForeground Black -ContentBackground LightSeaGreen "@ }注意:如果
New-WPFMessageBox函数未在目标会话中预先加载,需将函数定义嵌入到执行的命令块中。
方法二:向每个用户会话执行指定脚本
你提出的在用户会话中执行指定PowerShell脚本的思路可落地,具体实现如下:
脚本内容(原英文脚本转中文注释)
Add-Type -AssemblyName PresentationFramework function New-WPFMessageBox { [CmdletBinding()] param ( [Parameter(Mandatory=$true)] [System.Windows.UIElement]$Content, [string]$Title = "消息弹窗", [System.Windows.Media.Brush]$TitleBackground = [System.Windows.Media.Brushes]::DarkBlue, [System.Windows.Media.Brush]$TitleTextForeground = [System.Windows.Media.Brushes]::White, [System.Windows.Media.Brush]$ContentBackground = [System.Windows.Media.Brushes]::White ) # 创建主窗口 $window = New-Object System.Windows.Window $window.Title = $Title $window.WindowStyle = [System.Windows.WindowStyle]::SingleBorderWindow $window.SizeToContent = [System.Windows.SizeToContent]::WidthAndHeight $window.ResizeMode = [System.Windows.ResizeMode]::NoResize $window.Topmost = $true $window.WindowStartupLocation = [System.Windows.WindowStartupLocation]::CenterScreen # 构建标题栏 $titleGrid = New-Object System.Windows.Controls.Grid $titleGrid.Background = $TitleBackground $titleGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height="Auto"})) $titleGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width="*"})) $titleGrid.ColumnDefinitions.Add((New-Object System.Windows.Controls.ColumnDefinition -Property @{Width="Auto"})) # 添加标题文本 $titleText = New-Object System.Windows.Controls.TextBlock $titleText.Text = $Title $titleText.Foreground = $TitleTextForeground $titleText.FontSize = 14 $titleText.FontWeight = "Bold" $titleText.Margin = New-Object System.Windows.Thickness(10,5,10,5) [System.Windows.Controls.Grid]::SetColumn($titleText, 0) $titleGrid.Children.Add($titleText) # 添加关闭按钮 $closeButton = New-Object System.Windows.Controls.Button $closeButton.Content = "X" $closeButton.Width = 30 $closeButton.Height = 25 $closeButton.Margin = New-Object System.Windows.Thickness(5) $closeButton.Add_Click({ $window.Close() }) [System.Windows.Controls.Grid]::SetColumn($closeButton, 1) $titleGrid.Children.Add($closeButton) # 构建内容容器 $contentGrid = New-Object System.Windows.Controls.Grid $contentGrid.Background = $ContentBackground $contentGrid.Margin = New-Object System.Windows.Thickness(10) $contentGrid.Children.Add($Content) # 组装主布局 $mainGrid = New-Object System.Windows.Controls.Grid $mainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height="Auto"})) $mainGrid.RowDefinitions.Add((New-Object System.Windows.Controls.RowDefinition -Property @{Height="*"})) [System.Windows.Controls.Grid]::SetRow($titleGrid, 0) [System.Windows.Controls.Grid]::SetRow($contentGrid, 1) $mainGrid.Children.Add($titleGrid) $mainGrid.Children.Add($contentGrid) $window.Content = $mainGrid # 显示弹窗并等待关闭 $window.ShowDialog() | Out-Null } # 示例内容面板 $StackPanel = New-Object System.Windows.Controls.StackPanel $StackPanel.Children.Add((New-Object System.Windows.Controls.TextBlock -Property @{Text="构建已完成!"; FontSize=16; Margin="0,0,0,10"})) $StackPanel.Children.Add((New-Object System.Windows.Controls.TextBlock -Property @{Text="提交ID: $($env:build_sourceversion)"; FontSize=12})) # 调用弹窗函数 New-WPFMessageBox -Content $StackPanel -Title "构建完成通知" -TitleBackground LightSeaGreen -TitleTextForeground Black -ContentBackground LightSeaGreen
批量执行脚本到所有用户会话
- 确保脚本文件
E:\Script-Popup\Popup-Message - Done.ps1在服务器上所有用户会话均可访问(如放在公共共享目录) - 遍历所有用户会话执行脚本:
# 获取所有活跃用户会话ID $sessionIds = quser | Select-Object -Skip 1 | ForEach-Object { ($_ -split '\s+')[2] } # 在每个会话中执行脚本 foreach ($id in $sessionIds) { psexec.exe -i $id powershell.exe -sta -File "E:\Script-Popup\Popup-Message - Done.ps1" }
内容的提问来源于stack exchange,提问作者vfdsabvdasvd
相关产品推荐
相关产品推荐

