1

I'm trying to get correct screen resolutions from remote computers using Invoke-Command and a PSSession but both methods report one resolution of 1024 x 768. There are two screens, 1920 x 1080 and 1280 x 720. This is not a DPI thing.

Executing the code below (remotely) outputs the below snippet. Executing interactively, the correct resolutions are reported. All the other working methods posted online have the same behavoir.

Output:

PS > Add-Type -AssemblyName System.Windows.Forms
PS > [System.Windows.Forms.Screen]::AllScreens

BitsPerPixel : 0
Bounds       : {X=0,Y=0,Width=1024,Height=768}
DeviceName   : WinDisc
Primary      : True
WorkingArea  : {X=0,Y=0,Width=1024,Height=768}

It's surprising nothing in CIM can get these details from MULTIPLE monitors remotely, that I have found. Maybe time for a feature request to beef up some CIM cmdlets in 7.

I guess a workaround could be creating a Scheduled task on all target computers that runs a script locally to output the info to a local file, then use remoting to get the file or data.

If anyone has overcome this, your feedback would be greatly appreciated amongst the rest of us with this roadblock.

PowerShell 7:

Name                           Value
----                           -----
PSVersion                      7.0.1
PSEdition                      Core
GitCommitId                    7.0.1
OS                             Microsoft Windows 10.0.18363
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

Windows PowerShell:

Name                           Value
----                           -----
PSVersion                      5.1.18362.752
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.18362.752
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Windows 10 Pro

Hardy
  • 11
  • 1
  • Why not using WMI/CIM? `Get-CimInstance -ClassName Win32_DesktopMonitor | Select-Object ScreenWidth, ScreenHeight` – Olaf Jun 10 '20 at 23:41
  • @Olaf: That's really the cmdlet I should be using but it doesn't report resolution whether interactively or remotely executed. I've tried this on multiple systems so maybe its a driver-related issue. – Hardy Jun 11 '20 at 00:41
  • That only works for __physical computers__ with a __physical monitor__ connected to it. Otherwise you always get the default 1024x768. I will not work for virtual machines where you're connected remotely. – Olaf Jun 11 '20 at 01:09
  • Allow me to clarify. The code is being executed on a remote, physical computer with physical monitors connected. I totally understand the VM limitations - makes perfect sense. However, when executing it **interactively/physically**, my posted code outputs correct info. Win32_DesktopMonitor outputs nothing for the width/height so I avoided using it. – Hardy Jun 11 '20 at 01:51

1 Answers1

0

I am not sure if this issue was resolved or not, but I am not able to find any way to get resolution of remote PC via powershell (i.e. using non-interactive session). Hence came up with the logic to get this via registry values :

Note :-

  • This script is tested with Windows 10 only
  • This will require remote user to have read access to registry value in variable "$videoRegistryPath"
$videoRegistryPath = 'HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\GraphicsDrivers\Configuration\'
$all_monitor_array_X=@()
$all_monitor_array_Y=@()

$screen_cnt= (Get-CimInstance -Namespace root\wmi -ClassName wmimonitorid -ErrorAction SilentlyContinue | measure )
$NumberOfScreens= $screen_cnt.Count

$allVideoGraphics = Get-ChildItem -Path ($videoRegistryPath).Replace('HKEY_LOCAL_MACHINE','HKLM:')

foreach ($instance in $allVideoGraphics ) {
     $allVideoGraphicsChild= Get-ChildItem -Path ($instance.Name).Replace('HKEY_LOCAL_MACHINE','HKLM:')
     if ($allVideoGraphicsChild.Property.Contains('PrimSurfSize.cx')) {
        $allVideoGraphicsChildProperty = Get-ItemProperty -Path ($allVideoGraphicsChild.Name).Replace('HKEY_LOCAL_MACHINE','HKLM:')
        $Screen_X= $allVideoGraphicsChildProperty.'PrimSurfSize.cx'
        $Screen_Y=$allVideoGraphicsChildProperty.'PrimSurfSize.cy'
        $all_monitor_array_X += $Screen_X
        $all_monitor_array_Y += $Screen_Y
      }
}

for ($i=0;$i -le ($NumberOfScreens-1);$i++){    
    [PSCustomObject]@{
       Values = $all_monitor_array_X[$i];
        Instance = "Monitor_"+($i)+"_x_coordinate";
        }
    [PSCustomObject]@{
        Values = $all_monitor_array_Y[$i];
        Instance = "Monitor_"+($i)+"_y_coordinate";
        }
} 

Hope this will help in this specific requirement to get resolution of remote computer using non-interactive session.

  • I don't see how this answers the "remote" part of the question (this answer is all local). Also, `-ErrorAction SilentlyContinue` is generally frowned upon as bad practice. – Winfred Jul 04 '22 at 20:41
  • -ErrorAction can be removed, no issue with that. This was just put in for my tool I am using for remote execution. This is working with remote execution in my case. Remote here means non-interactive session (user not logged in), which is issue encountered in initial post. This script can easily be modified for execution on remote computers as well. – Harjeet Sandhu Jul 05 '22 at 21:48