Difference between revisions of "Windows Desktop Screenshot Monitoring"

From Steak Wiki
Jump to navigationJump to search
(Created page with "Here are notes on setting up a screen capture / recording / desktop streaming for Windows 10 (02/2020). ==Easy Solution (non Win10)== In Windows 7 (I think) you can simply us...")
 
 
(14 intermediate revisions by one other user not shown)
Line 1: Line 1:
Here are notes on setting up a screen capture / recording / desktop streaming for Windows 10 (02/2020).
+
{{Template:ProprietarySoftware}}
  
==Easy Solution (non Win10)==
+
Here are notes on setting up desktop screen monitoring for Windows 10 (02/2020).
In Windows 7 (I think) you can simply use VLC from the command line.
 
  
"C:\Program Files\VideoLAN\VLC\vlc.exe" -I --dummy-quiet screen://  --screen-fps=3  :sout=#transcode{vcodec=MJPG,venc=ffmpeg{qmin=0,qmax=10},vb=800,width=320, height=240,acodec=none}:http{mux=mpjpeg,dst=:8088} :sout-keep
+
The intention is for this to be a way to monitor users computers, in case they get a virus or do something stupid (or someone unauthorized uses the computer). It is for security and is 0.2 FPS (yes, that's 1 picture every 5 seconds). It is not intended to be a video stream of the user working.
  
This was tested to work in 2008 server. (NOTE: Doesn't work in win10, without opening a video screen. see below.)
+
EDIT: 08/2021, just use Zoneminder 1.36 or 1.38 (when released). See this post which has some tips on setup:
 +
https://forums.zoneminder.com/viewtopic.php?f=42&t=30581&p=120570 and https://wiki.zoneminder.com/LibVNC
  
NOTE: make sure to open port in firewall.
 
  
test first in localhost on server.
 
  
then test remotely.
+
==tl;dr Win10 Solution for taking Desktop Screenshots and Serving over LAN==
 +
Use this powershell script
 +
<pre>
 +
[cmdletbinding()]           
 +
param(           
 +
  [string]$Width,           
 +
  [string]$Height,           
 +
  [String]$FileName = "Screenshot"  ,
 +
  [string]$path2 = "c:\LOCATIONTOSAVE\"         
  
firewall needs port opened for remote access.
+
)           
 +
#Function to take screenshot. This function takes the width and height of the screen that # #has           
 +
#to be captured           
  
 +
function Take-Screenshot{           
 +
[cmdletbinding()]           
 +
param(           
 +
[Drawing.Rectangle]$bounds,           
 +
[string]$path           
 +
)           
 +
  $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($path)           
 +
  $graphics.Dispose()           
 +
  $bmp.Dispose()           
 +
}           
  
 +
#Function to get the primary monitor resolution.           
 +
#This code is sourced from           
 +
# https://techibee.com/powershell/powershell-script-to-get-desktop-screen-resolution/1615           
  
testing VLC 3.0.8 (64 bit windows) now...
+
function Get-ScreenResolution {           
by default, 3.0.8 opens up a GUI. obnoxious.
+
$Screens = [system.windows.forms.screen]::AllScreens                       
 +
foreach ($Screen in $Screens) {           
 +
  $DeviceName = $Screen.DeviceName           
 +
  $Width  = $Screen.Bounds.Width           
 +
  $Height  = $Screen.Bounds.Height           
 +
  $IsPrimary = $Screen.Primary                       
 +
  $OutputObj = New-Object -TypeName PSobject           
 +
  $OutputObj | Add-Member -MemberType NoteProperty -Name DeviceName -Value $DeviceName           
 +
  $OutputObj | Add-Member -MemberType NoteProperty -Name Width -Value $Width           
 +
  $OutputObj | Add-Member -MemberType NoteProperty -Name Height -Value $Height           
 +
  $OutputObj | Add-Member -MemberType NoteProperty -Name IsPrimaryMonitor -Value $IsPrimary           
 +
  $OutputObj                       
 +
}           
 +
}           
  
from stckexchange
+
#Main script begins           
<pre>
 
You can use this:
 
  
vlc -I dummy --dummy-quiet {path_to_file}
+
#By default captured screenshot will be saved in %temp% folder           
 +
#You can override it here if you want 
 +
#orig         
 +
#$Filepath = join-path $env:temp $FileName
 +
#edit
 +
$Filepath = join-path $path2 $FileName         
  
As per @MC10's answer, the -intf dummy or -I dummy (they do the same thing) hides the GUI but still opens a second command line window. Use the additional --dummy-quiet option to hide this window too.  
+
[void] [Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")          
</pre>
+
[void] [Reflection.Assembly]::LoadWithPartialName("System.Drawing")           
  
but that doesn't fucking work
+
if(!($width -and $height)) {           
  
Looks like it's a windows 10 problem.
+
$screen = Get-ScreenResolution | ? {$_.IsPrimaryMonitor -eq $true}           
 +
$Width = $screen.Width           
 +
$Height = $screen.height           
 +
}           
  
It worked on 2008
+
$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, $Screen.Width, $Screen.Height)           
  
Let's look at other options.
+
Take-Screenshot -Bounds $bounds -Path "$Filepath.png"           
 +
#Now you have the screenshot
 +
</pre>
  
  https://github.com/aviloria/ScreenCaptureServer/releases
+
Call it every 1 minute in task scheduler with this .vbs script (must use vbs to be quiet, and not open a cmd window)
 +
<pre>
 +
Dim index, count
 +
count = 11
 +
For index = 1 To count
 +
  command = "powershell.exe -nologo -command C:\SCRIPTHERE"
 +
set shell = CreateObject("WScript.Shell")
 +
shell.Run command,0
 +
'this is in milliseconds
 +
WScript.Sleep 5000
 +
Next
 +
</pre>
  
https://github.com/rdp/screen-capture-recorder-to-video-windows-free
+
In order for this type of script to take a screenshot, it must run as the user "only when he is logged in" per the task scheduler settings. Do not run this in task scheduler as SYSTEM, or whether or not the user is logged in. See details below.
this just looks like a mess. popular, though. doesn't mean anything.
 
  
==Manual JPEG screen capture and server over HTTP==
+
===Grab Images via SMB===
 +
At this point, you have an updating file which is a screenshot. You can now grab this however you want. If you use something like Zoneminder (which can read an image file as a video stream) or Blue Iris (not sure if that can, but probably), you will have a video stream.
  
After all that, I decided the best solution is to do this manually.
+
Map the SMB drive to the recording server to grab the file without installing anything. Another option is to use apache w/authentication (or without).
Almost future proof.
 
  
Some apache server, with a program that just takes screenshots and puts them in the local dir.
+
==Details==
 +
===VLC works in Win7 Only===
 +
In Windows 7 (I think) you can simply use VLC from the command line.
 +
ref: https://www.axis.com/files/tech_notes/Desktop_MJPEG_Screen_Capture.pdf
 +
"C:\Program Files\VideoLAN\VLC\vlc.exe" -I --dummy-quiet screen://  --screen-fps=3  :sout=#transcode{vcodec=MJPG,venc=ffmpeg{qmin=0,qmax=10},vb=800,width=320, height=240,acodec=none}:http{mux=mpjpeg,dst=:8088} :sout-keep
  
Then Zoneminder, Blueiris, etc... server reads the jpg file.
+
This was tested to work in 2008 server. (NOTE: Doesn't work in win10, without opening a video screen. see below.)
that would work... forever.
 
  
trying xampp EDIT: i only need apache, so nix xampp, go with just apache on win. you have to
+
NOTE: make sure to open port in firewall.
use 3rd party builds, as they don't make binaries.
 
and autoscreen (sourceforge)
 
av gives warnings on autoscreen.  
 
  
but its bs
+
test first in localhost on server.
  
it doesn't really work because, it saves to a new file all the time. I could manually fix it but nope.
+
then test remotely.  
  
===Powershell Get Screenshot===
+
firewall needs port opened for remote access.
  
let's try this:
+
Let's look at other options.
  
<pre>
+
https://github.com/aviloria/ScreenCaptureServer/releases
[Reflection.Assembly]::LoadWithPartialName("System.Drawing")
 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
 
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
 
function screenshot($path)
 
{
 
    $width = 0;
 
    $height = 0;
 
    $workingAreaX = 0;
 
    $workingAreaY = 0;
 
  
    $screen = [System.Windows.Forms.Screen]::AllScreens;
+
https://github.com/rdp/screen-capture-recorder-to-video-windows-free
 +
this just looks like a mess. popular, though. doesn't mean anything.
  
    foreach ($item in $screen)
+
===Manual JPEG screen capture and server over HTTP for Win10===
    {
 
        if($workingAreaX -gt $item.WorkingArea.X)
 
        {
 
            $workingAreaX = $item.WorkingArea.X;
 
        }
 
  
        if($workingAreaY -gt $item.WorkingArea.Y)
+
After all that, I decided the best solution is to do this manually.
        {
+
Almost future proof.
            $workingAreaY = $item.WorkingArea.Y;
 
        }
 
 
 
        $width = $width + $item.Bounds.Width;
 
 
 
        if($item.Bounds.Height -gt $height)
 
        {
 
            $height = $item.Bounds.Height;
 
        }
 
    }
 
  
    $bounds = [Drawing.Rectangle]::FromLTRB($workingAreaX, $workingAreaY, $width, $height);
+
Some apache server, with a program that just takes screenshots and puts them in the local dir. You can bypass the apache server by using SMB, also. That avoids the need to install apache.
    $bmp = New-Object Drawing.Bitmap $width, $height;
 
    $graphics = [Drawing.Graphics]::FromImage($bmp);
 
  
    $graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size);
+
Then Zoneminder, Blueiris, etc... server reads the file.
  
    $bmp.Save($path);
+
I tried autoscreen (sourceforge)
 +
av gives warnings on autoscreen, which must be wrong.
  
    $graphics.Dispose();
+
It doesn't really work because, it saves to a new file all the time. I gave up at this point. Didn't look into this.
    $bmp.Dispose();
 
}
 
  
</pre>
+
====Powershell Get Screenshot====
Can be called with: screenshot "D:\screenshot.png"
+
I tried a few things, before finding one that worked.
  
you need to allow scripts, so:
+
You may to need to allow scripts (or pass the allow to the script in the
 +
powershell, i.e. bypassing the execution policy), so:
 
* https://www.tenforums.com/tutorials/54585-change-powershell-script-execution-policy-windows-10-a.html
 
* https://www.tenforums.com/tutorials/54585-change-powershell-script-execution-policy-windows-10-a.html
 
explains it well
 
explains it well
Line 120: Line 150:
 
  Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
 
  Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force
  
this is a few more steps than 7 used to have. scope and force is new. fun.
+
EDIT: Don't set -Scope current user or you will have to disable it later.
 
+
It's an entangled set of sub-permissions and if you enable some of them, you can't change the main ones. The scope is sub permissions, RemoteSigned
can't figure out that one.
+
being one of the main permissions.
 
 
trying this:
 
<pre>
 
[Reflection.Assembly]::LoadWithPartialName("System.Drawing")
 
function screenshot([Drawing.Rectangle]$bounds, $path) {
 
  $bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height
 
  $graphics = [Drawing.Graphics]::FromImage($bmp)
 
  
  $graphics.CopyFromScreen($bounds.Location, [Drawing.Point]::Empty, $bounds.size)
+
Keep in mind when saving png, that you may have to write somewhere other than c: which often doesn't have write permissions anymore.
 
 
  $bmp.Save($path)
 
 
 
  $graphics.Dispose()
 
  $bmp.Dispose()
 
}
 
 
 
$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, 1000, 900)
 
screenshot $bounds "C:\screenshot.png"
 
</pre>
 
may have to write somewhere other than c:
 
which often doesn't have write permissions anymore.
 
  
 
that didn't work
 
that didn't work
Line 153: Line 164:
 
   [string]$Height,             
 
   [string]$Height,             
 
   [String]$FileName = "Screenshot"  ,
 
   [String]$FileName = "Screenshot"  ,
   [string]$path2 = "c:\ProgramData\Apache\"           
+
   [string]$path2 = "c:\LOCATIONTOSAVE\"           
  
 
)             
 
)             
#requires making the apache folder. This is just my personal preference.
 
 
 
#Function to take screenshot. This function takes the width and height of the screen that # #has             
 
#Function to take screenshot. This function takes the width and height of the screen that # #has             
 
#to be captured             
 
#to be captured             
Line 178: Line 187:
 
#This code is sourced from             
 
#This code is sourced from             
 
# https://techibee.com/powershell/powershell-script-to-get-desktop-screen-resolution/1615             
 
# https://techibee.com/powershell/powershell-script-to-get-desktop-screen-resolution/1615             
 
  
 
function Get-ScreenResolution {             
 
function Get-ScreenResolution {             
Line 222: Line 230:
 
from: https://techibee.com/powershell/powershell-script-to-take-a-screenshot-of-your-desktop/1626
 
from: https://techibee.com/powershell/powershell-script-to-take-a-screenshot-of-your-desktop/1626
  
that works.
+
That works, but has some load on a 4 core PC from 2010.
OK
+
Not bad, but not great. I wouldn't run it more than every 10 seconds
 
+
or so.  
now to schedule it.
 
  
  
Line 232: Line 239:
  
 
from: https://superuser.com/questions/293445/windows-task-scheduler-schedule-task-to-run-once-every-10-seconds
 
from: https://superuser.com/questions/293445/windows-task-scheduler-schedule-task-to-run-once-every-10-seconds
not so bad
 
  
then just to serve the file on the web
+
But it's easier to just use a for loop in a script with a delay.
  
need to decipher apache
+
It ends up that the script that calls this in task scheduler must be vbs
on win
+
as it must be quiet. Powershell and cmd, both open boxes, the user will see. This is because the script MUST run as the USER, when they are LOGGED IN. You can't run as system, or another admin. We are taking a screenshot of their desktop, and that env must be setup.
  
https://serverfault.com/questions/320288/how-can-i-easily-password-protect-a-site-in-apache-windows
+
The vbs script that calls the above ps1 powershell might look something like
looks like i have to generate an htaccess file
+
<pre>
 +
Dim index, count
 +
count = 11
 +
For index = 1 To count
 +
command = "powershell.exe -nologo -command C:\SCRIPTHERE"
 +
set shell = CreateObject("WScript.Shell")
 +
shell.Run command,0
 +
'this is in milliseconds
 +
WScript.Sleep 5000
 +
Next
 +
</pre>
  
i'll do this on a unix machine. i don't trust the websites that you can enter passwords in
+
So it runs every 5 seconds for a minute. Then you set it to run in Task Scheduler. Just call it directly, no need to do anything else. Test in cmd line.
that's bad practice
 
  
do it on linux then copy over the htaccess file.
+
You can adjust the PixelFormat to get smaller PNG files in the above ps1 script. I used
 +
$bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height, Format16bppRgb555
  
todo: finish apache setup
+
==Improvements==
 +
* Lower Resource Usage
 +
* Higher FPS
 +
* Encode to H264 and serve low res stream over RTSP (too bad VLC doesn't work anymore)

Latest revision as of 05:57, 16 April 2023

Caution: This page discusses Proprietary Software which is known to do the following to computer users: Record their actions, Mine their personal data, Steal business secrets, and other nefarious things. Steakwiki recommends against using unknown and unvetted software whenever possible.


Here are notes on setting up desktop screen monitoring for Windows 10 (02/2020).

The intention is for this to be a way to monitor users computers, in case they get a virus or do something stupid (or someone unauthorized uses the computer). It is for security and is 0.2 FPS (yes, that's 1 picture every 5 seconds). It is not intended to be a video stream of the user working.

EDIT: 08/2021, just use Zoneminder 1.36 or 1.38 (when released). See this post which has some tips on setup: https://forums.zoneminder.com/viewtopic.php?f=42&t=30581&p=120570 and https://wiki.zoneminder.com/LibVNC


tl;dr Win10 Solution for taking Desktop Screenshots and Serving over LAN

Use this powershell script

[cmdletbinding()]            
param(            
  [string]$Width,            
  [string]$Height,            
  [String]$FileName = "Screenshot"  ,
  [string]$path2 = "c:\LOCATIONTOSAVE\"          

)            
#Function to take screenshot. This function takes the width and height of the screen that # #has            
#to be captured            

function Take-Screenshot{            
[cmdletbinding()]            
param(            
 [Drawing.Rectangle]$bounds,             
 [string]$path            
)             
   $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($path)            
   $graphics.Dispose()            
   $bmp.Dispose()            
}            

#Function to get the primary monitor resolution.            
#This code is sourced from             
# https://techibee.com/powershell/powershell-script-to-get-desktop-screen-resolution/1615            

function Get-ScreenResolution {            
 $Screens = [system.windows.forms.screen]::AllScreens                        
 foreach ($Screen in $Screens) {            
  $DeviceName = $Screen.DeviceName            
  $Width  = $Screen.Bounds.Width            
  $Height  = $Screen.Bounds.Height            
  $IsPrimary = $Screen.Primary                        
  $OutputObj = New-Object -TypeName PSobject            
  $OutputObj | Add-Member -MemberType NoteProperty -Name DeviceName -Value $DeviceName            
  $OutputObj | Add-Member -MemberType NoteProperty -Name Width -Value $Width            
  $OutputObj | Add-Member -MemberType NoteProperty -Name Height -Value $Height            
  $OutputObj | Add-Member -MemberType NoteProperty -Name IsPrimaryMonitor -Value $IsPrimary            
  $OutputObj                        
 }            
}            

#Main script begins            

#By default captured screenshot will be saved in %temp% folder            
#You can override it here if you want  
#orig          
#$Filepath = join-path $env:temp $FileName 
#edit
$Filepath = join-path $path2 $FileName           

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

if(!($width -and $height)) {            

 $screen = Get-ScreenResolution | ? {$_.IsPrimaryMonitor -eq $true}            
 $Width = $screen.Width            
 $Height = $screen.height            
}            

$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, $Screen.Width, $Screen.Height)            

Take-Screenshot -Bounds $bounds -Path "$Filepath.png"            
#Now you have the screenshot

Call it every 1 minute in task scheduler with this .vbs script (must use vbs to be quiet, and not open a cmd window)

Dim index, count
count = 11
For index = 1 To count
 command = "powershell.exe -nologo -command C:\SCRIPTHERE"
 set shell = CreateObject("WScript.Shell")
 shell.Run command,0
'this is in milliseconds
 WScript.Sleep 5000
Next

In order for this type of script to take a screenshot, it must run as the user "only when he is logged in" per the task scheduler settings. Do not run this in task scheduler as SYSTEM, or whether or not the user is logged in. See details below.

Grab Images via SMB

At this point, you have an updating file which is a screenshot. You can now grab this however you want. If you use something like Zoneminder (which can read an image file as a video stream) or Blue Iris (not sure if that can, but probably), you will have a video stream.

Map the SMB drive to the recording server to grab the file without installing anything. Another option is to use apache w/authentication (or without).

Details

VLC works in Win7 Only

In Windows 7 (I think) you can simply use VLC from the command line. ref: https://www.axis.com/files/tech_notes/Desktop_MJPEG_Screen_Capture.pdf

"C:\Program Files\VideoLAN\VLC\vlc.exe" -I --dummy-quiet screen://  --screen-fps=3   :sout=#transcode{vcodec=MJPG,venc=ffmpeg{qmin=0,qmax=10},vb=800,width=320, height=240,acodec=none}:http{mux=mpjpeg,dst=:8088} :sout-keep

This was tested to work in 2008 server. (NOTE: Doesn't work in win10, without opening a video screen. see below.)

NOTE: make sure to open port in firewall.

test first in localhost on server.

then test remotely.

firewall needs port opened for remote access.

Let's look at other options.

https://github.com/aviloria/ScreenCaptureServer/releases
https://github.com/rdp/screen-capture-recorder-to-video-windows-free

this just looks like a mess. popular, though. doesn't mean anything.

Manual JPEG screen capture and server over HTTP for Win10

After all that, I decided the best solution is to do this manually. Almost future proof.

Some apache server, with a program that just takes screenshots and puts them in the local dir. You can bypass the apache server by using SMB, also. That avoids the need to install apache.

Then Zoneminder, Blueiris, etc... server reads the file.

I tried autoscreen (sourceforge) av gives warnings on autoscreen, which must be wrong.

It doesn't really work because, it saves to a new file all the time. I gave up at this point. Didn't look into this.

Powershell Get Screenshot

I tried a few things, before finding one that worked.

You may to need to allow scripts (or pass the allow to the script in the powershell, i.e. bypassing the execution policy), so:

explains it well

Set-ExecutionPolicy RemoteSigned -Scope CurrentUser -Force

EDIT: Don't set -Scope current user or you will have to disable it later. It's an entangled set of sub-permissions and if you enable some of them, you can't change the main ones. The scope is sub permissions, RemoteSigned being one of the main permissions.

Keep in mind when saving png, that you may have to write somewhere other than c: which often doesn't have write permissions anymore.

that didn't work trying a different one...

[cmdletbinding()]            
param(            
  [string]$Width,            
  [string]$Height,            
  [String]$FileName = "Screenshot"  ,
  [string]$path2 = "c:\LOCATIONTOSAVE\"          

)            
#Function to take screenshot. This function takes the width and height of the screen that # #has            
#to be captured            

function Take-Screenshot{            
[cmdletbinding()]            
param(            
 [Drawing.Rectangle]$bounds,             
 [string]$path            
)             
   $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($path)            
   $graphics.Dispose()            
   $bmp.Dispose()            
}            

#Function to get the primary monitor resolution.            
#This code is sourced from             
# https://techibee.com/powershell/powershell-script-to-get-desktop-screen-resolution/1615            

function Get-ScreenResolution {            
 $Screens = [system.windows.forms.screen]::AllScreens                        
 foreach ($Screen in $Screens) {            
  $DeviceName = $Screen.DeviceName            
  $Width  = $Screen.Bounds.Width            
  $Height  = $Screen.Bounds.Height            
  $IsPrimary = $Screen.Primary                        
  $OutputObj = New-Object -TypeName PSobject            
  $OutputObj | Add-Member -MemberType NoteProperty -Name DeviceName -Value $DeviceName            
  $OutputObj | Add-Member -MemberType NoteProperty -Name Width -Value $Width            
  $OutputObj | Add-Member -MemberType NoteProperty -Name Height -Value $Height            
  $OutputObj | Add-Member -MemberType NoteProperty -Name IsPrimaryMonitor -Value $IsPrimary            
  $OutputObj                        
 }            
}            

#Main script begins            

#By default captured screenshot will be saved in %temp% folder            
#You can override it here if you want  
#orig          
#$Filepath = join-path $env:temp $FileName 
#edit
$Filepath = join-path $path2 $FileName           

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

if(!($width -and $height)) {            

 $screen = Get-ScreenResolution | ? {$_.IsPrimaryMonitor -eq $true}            
 $Width = $screen.Width            
 $Height = $screen.height            
}            

$bounds = [Drawing.Rectangle]::FromLTRB(0, 0, $Screen.Width, $Screen.Height)            

Take-Screenshot -Bounds $bounds -Path "$Filepath.png"            
#Now you have the screenshot

from: https://techibee.com/powershell/powershell-script-to-take-a-screenshot-of-your-desktop/1626

That works, but has some load on a 4 core PC from 2010. Not bad, but not great. I wouldn't run it more than every 10 seconds or so.


A Windows Task Scheduler trigger cannot repeat more often than every 1 minute, but you can set up multiple triggers. To run a task every 10 seconds, add six Triggers. Each one should run the task Daily, and Repeat task every 1 minute. Their start times should be 12:00:00 AM, 12:00:10 AM, 12:00:20 AM, 12:00:30 AM, 12:00:40 AM, and 12:00:50 AM.

from: https://superuser.com/questions/293445/windows-task-scheduler-schedule-task-to-run-once-every-10-seconds

But it's easier to just use a for loop in a script with a delay.

It ends up that the script that calls this in task scheduler must be vbs as it must be quiet. Powershell and cmd, both open boxes, the user will see. This is because the script MUST run as the USER, when they are LOGGED IN. You can't run as system, or another admin. We are taking a screenshot of their desktop, and that env must be setup.

The vbs script that calls the above ps1 powershell might look something like

Dim index, count
count = 11
For index = 1 To count
 command = "powershell.exe -nologo -command C:\SCRIPTHERE"
 set shell = CreateObject("WScript.Shell")
 shell.Run command,0
'this is in milliseconds
 WScript.Sleep 5000
Next

So it runs every 5 seconds for a minute. Then you set it to run in Task Scheduler. Just call it directly, no need to do anything else. Test in cmd line.

You can adjust the PixelFormat to get smaller PNG files in the above ps1 script. I used

$bmp = New-Object Drawing.Bitmap $bounds.width, $bounds.height, Format16bppRgb555

Improvements

  • Lower Resource Usage
  • Higher FPS
  • Encode to H264 and serve low res stream over RTSP (too bad VLC doesn't work anymore)