2

我想向我网络中的远程计算机发送“气球通知”。网络中的每台机器都在 Windows 10 上运行。该事件需要从使用 php 构建的网站触发。我已经通过使用以下代码完成了这项工作:

php

$powershell_path = "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe";
$script_path = "[..path to the ps1 script..]\\test.ps1";

$exec = $powershell_path." -executionPolicy Unrestricted ".$script_path." -computer_name ".$args['remote_computer'];
shell_exec($exec." 2>&1");

测试.ps1

param(
    [parameter(mandatory=$true)][string]$computer_name
)

function Send-Balloon {

    Param(
        [parameter(mandatory=$true)][string]$To,
        [parameter(mandatory=$true)][string]$balloon_title,
        [parameter(mandatory=$true)][string]$balloon_text,
        [parameter(mandatory=$false)][int]$show_time,
        [parameter(mandatory=$false)][string]$scripts_path,
        [parameter(mandatory=$false)][string]$script_name
    )

    if(!$show_time) { $show_time = 15000 }
    if(!$scripts_path) { $scripts_path = "C:\temp\" }
    if(!$script_name) { $script_name = "task.ps1" }

    $remote_computer = $To

    if(!(Test-Connection -ComputerName $remote_computer -Count 1 -ErrorAction     SilentlyContinue)) {
        Write-Warning "$remote_computer could not be reached"
        break
    }

    $str = @"
        Add-Type -AssemblyName  System.Windows.Forms
        `$balloon = [System.Windows.Forms.NotifyIcon]::new()
        `$path = (Get-Process -id `$pid).Path
        `$balloon.Icon = [System.Drawing.Icon]::ExtractAssociatedIcon(`$path)
        `$balloon.BalloonTipIcon  = [System.Windows.Forms.ToolTipIcon]::Info
        `$balloon.BalloonTipTitle = '$balloon_title'
        `$balloon.BalloonTipText  = '$balloon_text'
        `$balloon.Visible  = `$true
        `$balloon.ShowBalloonTip(100000)
    "@

    $script = [scriptblock]::Create($str)
    $script | Out-File $scripts_path\$script_name
    $remote_path = "\\$remote_computer\c$\temp"

    if(!(Test-Path $remote_path)) {
        New-Item -ItemType Directory -Path $remote_path
    }
    Copy-Item -Path $scripts_path\$script_name -Destination $remote_path

    $task_scriptblock = {
        $schedule_script = 'C:\temp\task.ps1'
        $seconds = 2
        $a = New-ScheduledTaskAction -Execute "powershell.exe" -Argument "-WindowStyle hidden -Command $schedule_script"
        $tr = New-ScheduledTaskTrigger -Once -At ((Get-Date) + (New-TimeSpan -Seconds $seconds))
        $p = New-ScheduledTaskPrincipal -UserId (Get-CimInstance -ClassName Win32_ComputerSystem | Select-Object -expand UserName)
        $tn = "!random_task_name_" + (-join ((65..90) + (97..122) | Get-Random -Count 10 | % {[char]$_}))
        $t = Register-ScheduledTask -TaskName $tn -Trigger $tr -Action $a -Principal $p
        Start-Sleep ($seconds + 1)
        Get-ScheduledTask -TaskName $tn | Unregister-ScheduledTask -Confirm:$false
        Remove-Item -Path $schedule_script
    }
    Invoke-Command -ComputerName $remote_computer -ScriptBlock $task_scriptblock 
}

Send-Balloon -To $computer_name -balloon_title "test" -balloon_text "just a test"

此代码将脚本从 $str 复制到给定远程计算机的临时文件夹中。然后它告诉远程计算机执行创建的文件。执行后会删除 ps1 文件。

这就像意图和(大部分)完美无瑕。我现在的问题是,带有“-WindowStyle hidden”的powershell并没有真正隐藏。有一瞬间,您可以看到 powershell 控制台弹出并立即消失。我读过这是“正常”行为,可以通过从另一个上下文(如 vbs 脚本)调用 ps1 文件来抵消。

VB

command = "powershell.exe -nologo -command [path to the ps1-file]"
set shell = CreateObject("WScript.Shell")
shell.Run command,0

问题是,这似乎过于复杂,因为我确实有一个 php 脚本来运行 ps1 脚本来复制 ps1 和 vbs 文件。然后调用复制的 vbs 脚本,该脚本调用复制的 ps1 来显示一个简单的通知。

有没有一种简单的方法可以在远程计算机上通过 php 调用 ps1 脚本而无需看到 powershell 控制台?甚至更好:有没有更简单的方法可以在我还没有想到的远程计算机上触发“气球通知”?

4

0 回答 0