Take screenshot script

Hello,

I want to request how to create a script that when run, takes a screenshot (or print scrn) of endpoint its run on. Then save that image to a specified folder or network location. Even better have it emailed along with the alert. This would be userful for seeing if a computer is in use before remoting into it. As well could be used in conjunction with a monitor. For example, if a monitor is watching for a crashed application, when detected it can run this script to a screenshot. This would be helpful to determine what the user was doing at the time of the event, greatly aiding troubleshooting.

Thanks!

Hi @eztech

We will analyze the request and let you know once we complete the script.

Thanks

I took a stab at it using a powershell script run by python. It works good and takes a screenshot of multiple monitors even. I guess the only piece I’d love to add is the ability to email the screenshot in addition to saving it

import time;
import os;
import re;
import ctypes
file='C:\\Windows\Temp\Take-ScreenShot.ps1';
input="""
#############################################################################
# Capturing a screenshot
#############################################################################
$timer = (Get-Date -Format yyy-mm-dd-hhmm)
$File = "$env:userprofile\$env:computername-$env:username-$timer.bmp"
Add-Type -AssemblyName System.Windows.Forms
Add-type -AssemblyName System.Drawing
# Gather Screen resolution information
$Screen = [System.Windows.Forms.SystemInformation]::VirtualScreen
$Width = $Screen.Width
$Height = $Screen.Height
$Left = $Screen.Left
$Top = $Screen.Top
# Create bitmap using the top-left and bottom-right bounds
$bitmap = New-Object System.Drawing.Bitmap $Width, $Height
# Create Graphics object
$graphic = [System.Drawing.Graphics]::FromImage($bitmap)
# Capture screen
$graphic.CopyFromScreen($Left, $Top, 0, 0, $bitmap.Size)
# Save to file
$bitmap.Save($File) 
Write-Output "Screenshot saved to:"
Write-Output $File

"""
fobj=open(file,"w");
fobj.write(input);
fobj.close();

class disable_file_system_redirection:
    _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection
    _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection
    def __enter__(self):
        self.old_value = ctypes.c_long()
        self.success = self._disable(ctypes.byref(self.old_value))
    def __exit__(self, type, value, traceback):
        if self.success:
            self._revert(self.old_value)


with disable_file_system_redirection():
    out=os.popen(r'powershell.exe -executionpolicy bypass -file C:\Windows\Temp\Take-ScreenShot.ps1').read();
    print(out);

os.remove(file);

Hi @eztech

We are already processing your request. We will share the appropriate script soon.

Thanks

Hi Guys,

this is a fab idea; but why not just do a proper implementation of this into the system / workflow?

In ITSM have the ability to take a screenshot which is taken and uploaded to ITSM; you as the admin can then view this and click create ticket from screenshot if needed which takes you to ServiceDesk new ticket window with this attached.

Scripts are Ok, but we have an agent on peoples computers for a reason… Lets use it!

Couldnt agree more! I find powershell more powerful than python for windows, but only because I dont know much about python. Because they havent gotten back to me, I have refined my screenshot script. Its just powershell wrapped in python but works great. It takes a screenshot, converts it from BMP to png, emails it and removes the file from the computer. Has to be run as logged on user


import time;
import os;
import re;
import ctypes
file='C:\\Windows\Temp\Take-ScreenShot.ps1';
input="""
#############################################################################
# Capturing a screenshot
#############################################################################
$timer = (Get-Date -Format yyy-mm-dd-hhmm)
$File = "$env:userprofile\$env:computername-$env:username-$timer.bmp"
Add-Type -AssemblyName System.Windows.Forms
Add-type -AssemblyName System.Drawing
# Gather Screen resolution information
$Screen = [System.Windows.Forms.SystemInformation]::VirtualScreen
$Width = $Screen.Width
$Height = $Screen.Height
$Left = $Screen.Left
$Top = $Screen.Top
# Create bitmap using the top-left and bottom-right bounds
$bitmap = New-Object System.Drawing.Bitmap $Width, $Height
# Create Graphics object
$graphic = [System.Drawing.Graphics]::FromImage($bitmap)
# Capture screen
$graphic.CopyFromScreen($Left, $Top, 0, 0, $bitmap.Size)
# Save to file
$bitmap.Save($File) 
Write-Output "Screenshot saved to:"
Write-Output $File
$fileType = $file.Substring(($file.IndexOf('.'))+1) #get image file extension

function do_mail ($myhtml) {

$SMTPServer = "smtp.office365.com"
$SMTPPort = "587"
$Username = "username@email.com"
$Password = "emailpassword"
$time = Get-Date
$to = "to@address.com"
$subject = "Screenshot of $env:computername on $time"
$body = @"
<html>
<body>
<img src="cid:$env:computername-$env:username-$timer.jpg">
</body>
</html>
"@
$attachment = New-Object System.Net.Mail.Attachment -ArgumentList $filepath
$attachment.ContentDisposition.Inline = $True
$attachment.ContentDisposition.DispositionType = "Inline"
$fileType = $filepath.Substring(($filepath.IndexOf('.'))+1) #get image file extension
$attachment.ContentType.MediaType = "image/$fileType" #set mediaType based on $file extension
$attachment.ContentId = '$env:computername-$env:username-$timer.jpg'


$message = New-Object System.Net.Mail.MailMessage
$message.IsBodyHTML = $true
$message.subject = $subject
$message.body = $body
$message.to.add($to)
#$message.cc.add($cc)
$message.from = $username
$message.attachments.add($attachment)

$smtp = New-Object System.Net.Mail.SmtpClient($SMTPServer, $SMTPPort);
$smtp.EnableSSL = $true
$smtp.Credentials = New-Object System.Net.NetworkCredential($Username, $Password);
$smtp.send($message)
$attachment.Dispose();
$message.Dispose();
write-host "Email sent to $to"
Remove-Item $filepath
} 

# Try uncommenting the following line if you receive errors about a missing assembly
[void][System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
function ConvertTo-Jpg
{
  [cmdletbinding()]
  param([Parameter(Mandatory=$true, ValueFromPipeline = $true)] $Path)

  process{
    $qualityEncoder = [System.Drawing.Imaging.Encoder]::Quality
    $encoderParams = New-Object System.Drawing.Imaging.EncoderParameters(1)

    # Set JPEG quality level here: 0 - 100 (inclusive bounds)
    $encoderParams.Param[0] = New-Object System.Drawing.Imaging.EncoderParameter($qualityEncoder, 50)
    $jpegCodecInfo = [System.Drawing.Imaging.ImageCodecInfo]::GetImageEncoders() | where {$_.MimeType -eq 'image/jpeg'}

    if ($Path -is [string]) {
      $Path = get-childitem $Path
    }

    $Path | foreach {
      $image = [System.Drawing.Image]::FromFile($($_.FullName))
      $filePath =  "{0}\{1}.jpg" -f $($_.DirectoryName), $($_.BaseName)
      $image.Save($filePath, $jpegCodecInfo, $encoderParams)
      $image.Dispose()
      Write-host "File converted to JPG"
      write-host $filepath

    }

    do_mail $myhtml

  }

}

#Use function:
# cd to directory with png files
#cd c:\users\$env:username

#Run ConvertTo-Jpg function and send email
Get-ChildItem $file | ConvertTo-Jpg
#Remove BMP
Remove-Item $file
"""
fobj=open(file,"w");
fobj.write(input);
fobj.close();

class disable_file_system_redirection:
    _disable = ctypes.windll.kernel32.Wow64DisableWow64FsRedirection
    _revert = ctypes.windll.kernel32.Wow64RevertWow64FsRedirection
    def __enter__(self):
        self.old_value = ctypes.c_long()
        self.success = self._disable(ctypes.byref(self.old_value))
    def __exit__(self, type, value, traceback):
        if self.success:
            self._revert(self.old_value)


with disable_file_system_redirection():
    out=os.popen(r'powershell.exe -executionpolicy bypass -file C:\Windows\Temp\Take-ScreenShot.ps1').read();
    print(out);

os.remove(file);

Cool bit of code.

thanks for the share

Hi @eztech

We regret delay from our side for this request.

Thank you for sharing your script with our forum community. It is working great, highly appreciate your effort.

We had published the same script in the below-mentioned link to benefit others.

https:/scripts.comodo.com/frontend/web/topic/procedure-to-take-a-screenshot-and-send-it-in-an-email

Thanks
kannan