为什么我的屏幕截图功能无法作为作业使用

Why does my Screenshot Function not work as a Job

我在作业中有一个功能可以截取屏幕截图。脚本本身由 Taskscheduler 作为域管理员执行。我也检查了 "Run with highest privileges".

作业应该先截屏然后发送电子邮件,但这两种情况都不会发生。我也没有看到错误消息(可能是因为它是后台作业?)。也许电子邮件未发送是因为它想将屏幕截图附加到电子邮件中,但不能,因为屏幕截图未创建。

为什么我的功能不能截图?域管理员有权写入目标。当我 运行 start-job 之外的函数时创建屏幕截图。如果我在 start-job 中有函数,它不会被创建,脚本是通过 Taskscheduler 还是手动启动都没有关系。

我错过了什么?

以下代码启动作业并截取屏幕截图:

Start-Job -Name LogikWebserverWatch {

    function Take-Screenshot([string]$outfile) 
    {
    [int]$PrtScrnWidth = (gwmi Win32_VideoController).CurrentHorizontalResolution
    [int]$PrtScrnHeight = (gwmi Win32_VideoController).CurrentVerticalResolution
    $bounds = [Drawing.Rectangle]::FromLTRB(0, 0, $PrtScrnWidth, $PrtScrnHeight)
    $bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height
    $graphics = [Drawing.Graphics]::FromImage($bmp)
    $graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)
    $bmp.Save($outfile)
    $graphics.Dispose()
    $bmp.Dispose()
    }

    while ((Get-Process LogikWebserver).Responding) {sleep -Milliseconds 50}

    if (!(Get-Process LogikWebserver).Responding) {
    Try{

        $utf8 = New-Object System.Text.utf8encoding
        $datetime = (get-date).ToString('yyyyMMdd-HHmmss')
        Take-Screenshot -outfile C:\Install\LogikWebserverErrorReporting\Screenshot-$datetime.png
        # some more code [...]
    } Catch {  some more code [...] }
}}

The documentations 表示:

A Windows PowerShell background job runs a command without interacting with the current session.

因此您可能必须在作业中加载所需的程序集才能运行。

当我尝试上面的代码时,它只在 运行 工作之外创建了一个屏幕截图(如你所提到的),但是将此行添加到 Start-Job [=14] 的顶部=] 也使它在工作内部工作:

[Reflection.Assembly]::LoadWithPartialName("System.Drawing")

或者,如上所示,现在已弃用:

[System.Reflection.Assembly]::LoadFrom("C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Drawing.dll")

或者

Add-Type "C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.6.1\System.Drawing.dll"

请注意,当 运行从计划任务执行时,我没有对此进行测试。

不要使用功能。只需像这样在脚本块中编写您的函数代码:

Start-Job -Name LogikWebserverWatch {
    Add-Type -AssemblyName "System.Drawing"
    [int]$PrtScrnWidth = (gwmi Win32_VideoController).CurrentHorizontalResolution
    [int]$PrtScrnHeight = (gwmi Win32_VideoController).CurrentVerticalResolution
    $bounds = [Drawing.Rectangle]::FromLTRB(0, 0, $PrtScrnWidth, $PrtScrnHeight)
    $bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height
    $graphics = [Drawing.Graphics]::FromImage($bmp)
    $graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)
    $bmp.Save($outfile)
    $graphics.Dispose()
    $bmp.Dispose()
    }

    while ((Get-Process LogikWebserver).Responding) {sleep -Milliseconds 50}

 if (!(Get-Process LogikWebserver).Responding) {
    Try{

        $utf8 = New-Object System.Text.utf8encoding
        $datetime = (get-date).ToString('yyyyMMdd-HHmmss')
        Take-Screenshot -outfile C:\Install\LogikWebserverErrorReporting\Screenshot-$datetime.png
        # some more code [...]
    } Catch {  some more code [...] }
}