LogoLogo
TwitterLinkedInGitHubPowerShell Gallery
  • About
  • Events
  • Blog
    • 2022
      • 🆕OSD January Update
      • 🆕PSCloudScript Basics
    • 2021
      • Start-OOBEDeploy
      • OSDCloud
      • PowerShell Gallery in WinPE
      • BitLocker KeyProtectors
      • WindowsCapability -and WindowsPackage
      • Scheduled Tasks
        • Building a Task
        • Task Permissions
        • Task Trigger
        • Action a PowerShell File
        • Action a PS Encoded Script
        • Conclusion
          • Windows Activation and Edition Change
          • REG.exe and Multiple Actions
    • 2019
      • 2019-02
        • Offline Servicing vs Reference Image
      • 2019-04
        • Windows 10 Upgrade MultiLang (Uno)
      • 2019-06
        • Offline Servicing Windows 10 with CU for .NET 4.8
        • OSDBuilder and .NET CU KB4480056
      • 2019-09
        • Black Screen During Windows 10 Setup
      • 2019-11
        • I Hate OSDBuilder
    • 2018
      • WinPE 10 1809 WPF DLL Fix
      • Microsoft Update Releases
      • Create WinPE.wim from Boot.wim or WinRE.wim
      • Windows Setup: FAT32 USB with +4GB Install.wim
      • Windows 10 from ESD
      • Windows 10 1809 Appx Issues
      • Mount-WindowsImage -Optimize
  • Guides
    • Autopilot App Registration
    • PSCloudScript
      • PS Cmdlets
      • GitHub Gist
      • GitHub Git Repo
      • Content-Type | Azure Static Web App
      • Command Shortening
      • Azure Key Vault Secret
      • OSD PowerShell Module
      • PSCloudScript Examples
        • Autopilot
        • AutopilotOOBE
        • OSDCloud Live
        • WinPE PowerShell Gallery
        • OSDCloud WinPE and OOBE
    • go OSDCloud
      • Azure Function
      • Custom Domain
      • SSL Binding
      • Proxies
  • PowerShell
    • OSD
    • OSDCloud
    • OSDBuilder (Offline Servicing)
    • OSDSUS (Update Catalogs)
    • OSDUpdate (MS Updates)
    • OSDDrivers (Compact Drivers)
    • PShot
      • Release Notes
      • Usage
        • -Directory
        • $AutoPath
        • -Prefix
        • -Count
        • -Delay
        • -Clipboard
        • -Primary
        • The Object
      • Technical
        • Why a Module?
        • Resolution, Scale and DPI
Powered by GitBook
On this page
  • Display Scale of High Res Screens
  • PowerShell, ISE, and Windows Terminal
  • DPI
  1. PowerShell
  2. PShot
  3. Technical

Resolution, Scale and DPI

PreviousWhy a Module?

Last updated 4 years ago

This page is under construction

Most PowerShell screenshot utilities follow a standard practice, which is to get the screen resolution of the VirtualScreen

Add-Type -AssemblyName System.Windows.Forms
[System.Windows.Forms.SystemInformation]::VirtualScreen

When running this command in Windows Terminal, it gives me a Width x Height of 1920 x 1080 (1080p)

Display Scale of High Res Screens

The problem is that my screen is not 1080p, but rather, it is a 4K screen. So why does VirtualScreen only see 1080p? That's because on my laptop, I have the scale set to 200%

So when I use any other PowerShell screenshot utility, the captured image is 1080p instead of 4K. This makes my full screen Windows Settings look like this

So in my case, I need to multiply the VirtualScreen 1920 x 1080 by 200% to get my true resolution of 3840 x 2160 (4K)

PowerShell, ISE, and Windows Terminal

Things get worse because there is no uniformity between the different flavors of PowerShell. Remember Windows Terminal shows 1080p

And Windows PowerShell shows 1080p

But PowerShell ISE shows the real 4K of 3840 x 2160

DPI

The solution is to determine the Scale by pulling the information from the DPI class. In the script below, it results in 200 (percent). This matches the Scale from my Windows Settings

Add-Type @'
using System; 
using System.Runtime.InteropServices;
using System.Drawing;

public class DPI {  
  [DllImport("gdi32.dll")]
  static extern int GetDeviceCaps(IntPtr hdc, int nIndex);

  public enum DeviceCap {
  VERTRES = 10,
  DESKTOPVERTRES = 117
  } 

  public static float scaling() {
  Graphics g = Graphics.FromHwnd(IntPtr.Zero);
  IntPtr desktop = g.GetHdc();
  int LogicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.VERTRES);
  int PhysicalScreenHeight = GetDeviceCaps(desktop, (int)DeviceCap.DESKTOPVERTRES);

  return (float)PhysicalScreenHeight / (float)LogicalScreenHeight;
  }
}
'@ -ReferencedAssemblies 'System.Drawing.dll' -ErrorAction Stop
Return [DPI]::scaling() * 100