2

Our current scenario is this:

We have more than 80 tablet computers (running Windows 10) in our network that run under the same user (DefaultUser). In order to verify that the display settings are correctly set, we would like to use a powershell script to automatically check the used resolution remotely with a support user account.

So far, we know how to get the primary screen resolution for the user under which the script gets executed (which is rather easy):

 // get primary screen width Add-Type -AssemblyName System.Windows.Forms [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Width // height accordingly 

In case we execute this script on one of the tablets using the support account, we get the primary screen resolution for the support account user - but not for the desired user DefaultUser.

How can we get the resolution for the DefaultUser?

The only solution that easily comes to my mind is a rather ugly thing: Using the windows task scheduler i could create a task that executes the script (under the defaultUser) to get the screen resolution and write the result(s) into a file that can be accessed by the support user account. But i am looking for something more elegant.

8
  • Is DefaultUser logged in? Is the support user running as admin or system? Commented Sep 22, 2022 at 9:17
  • @Anders : yes, the DefaultUser is logged in. The support user is running with system privileges. Commented Sep 22, 2022 at 12:50
  • Did you already try runas.exe? Commented Sep 26, 2022 at 12:06
  • @stackprotector : No. How would a command to call a powershell script look like to return the resolution. Can you provide a fully working solution? Commented Sep 27, 2022 at 7:28
  • 2
    I'm not sure this question can be answered. To the best of my knowledge, Windows does not support per-user resolution settings. It's only stored at the system level (at the HKEY_LOCAL_MACHINE hive path mentioned above or at HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Hardware Profiles/Current/System/CurrentControlSet/Video/). That's why software like "Carroll" exists which provides that functionality. Commented Sep 28, 2022 at 13:04

2 Answers 2

4

You may be able to use CIM or WMI to get from point a to b.

CIM_VideoController is the class that would contain the resolution.

Using PowerShell Core:

Get-CimInstance CIM_VideoController | Select SystemName, CurrentHorizontalResolution, CurrentVerticalResolution 

Using Windows PowerShell:

Get-WmiObject Win32_VideoController | Select SystemName, CurrentHorizontalResolution, CurrentVerticalResolution 

You should be able to open the proper ports to use either of these options remotely (though you could also probably get away with using Invoke-Command to run them, as long as you use CredSSP or Kerberos Delegation to take the 2nd hop problem into account).

Sign up to request clarification or add additional context in comments.

2 Comments

These command work, but yields the resolution for the currently active user only. Is there a way to get the resolution for another logged-in user (defaultUser)?
PowerShell does not support kerberos double hop scenarios. For this CredSSP is available or you have to passover the credentials into the remote session.
2

It sounds like you're looking for the screen scaling values, based on your code checking the PrimaryScreen values:

# My monitor resolution is 3000x2000 Add-Type -AssemblyName System.Windows.Forms # [Screen] returns screen size AFTER scaling (200% here) [System.Windows.Forms.Screen]::PrimaryScreen.Bounds.Height 1000 # [SystemInformation] returns the hardware screen resolution (applies to all users) [System.Windows.Forms.SystemInformation]::VirtualScreen.Height 2000 

Scaling can be set on a per-user basis, though there is a machine-wide "Default" setting. Screen scaling is weird, and gets done differently depending on what version of windows you have. Here's how it works in Windows 10 at least.

You can check the current values like so:

# AllUsers setting, which shows as (default) Get-ItemProperty -path "HKCU:\Control Panel\Desktop\WindowMetrics" | fl AppliedDPI # User's current scaling setting (I use a * instead of the per-monitor ID) Get-ItemProperty -path "HKCU:\Control Panel\Desktop\PerMonitorSettings\*" | fl DpiValue 
# AppliedDPI shows the "Default" scaling setting on a system level like: 96 : 100% 120 : 125% 144 : 150% 192 : 200% (my default) # DpiValue shows how many steps up or down the current user's scaling setting is. For example on my machine: #250% DpiValue : 2 # +2 #200% (default) DpiValue : 0 #150% DpiValue : 4294967294 # -1 #100% DpiValue : 4294967292 # -3 

Finding and overriding scaling for other user profiles is pretty involved, but has been done by other people. I found this script and usage details by user romaliceishimwe2. I have not tested, but it does show how to look at and change other users' profiles:

#First we configure the default, later we will configure any existing users. #Load the ntuser.dat of the default user REG LOAD HKU\Default_User C:\users\default\ntuser.dat #Assign new registry keys New-ItemProperty -path registry::"HKU\Default_User\Control Panel\Desktop" -Name LogPixels -Value 120 -Type DWord New-ItemProperty -path registry::"HKU\Default_User\Control Panel\Desktop" -Name Win8DpiScaling -Value 1 -Type DWord #unload default user ntuser.dat REG UNLOAD HKU\Default_User #Here we configure any eixting users # Regex pattern for SIDs $PatternSID = 'S-1-5-21-\d+-\d+\-\d+\-\d+$' # Get Username, SID, and location of ntuser.dat for all users $ProfileList = gp 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\ProfileList\*' | Where-Object {$_.PSChildName -match $PatternSID} | Select @{name="SID";expression={$_.PSChildName}}, @{name="UserHive";expression={"$($_.ProfileImagePath)\ntuser.dat"}}, @{name="Username";expression={$_.ProfileImagePath -replace '^(.*[\\\/])', ''}} # Get all user SIDs found in HKEY_USERS (ntuder.dat files that are loaded) $LoadedHives = gci Registry::HKEY_USERS | ? {$_.PSChildname -match $PatternSID} | Select @{name="SID";expression={$_.PSChildName}} # Get all users that are not currently logged $UnloadedHives = Compare-Object $ProfileList.SID $LoadedHives.SID | Select @{name="SID";expression={$_.InputObject}}, UserHive, Username # Loop through each profile on the machine Foreach ($item in $ProfileList) { # Load User ntuser.dat if it's not already loaded IF ($item.SID -in $UnloadedHives.SID) { reg load HKU\$($Item.SID) $($Item.UserHive) | Out-Null } ##################################################################### # This is where you can read/modify a users portion of the registry "{0}" -f $($item.Username) | Write-Output New-ItemProperty -path registry::"HKU\$($Item.SID)\Control Panel\Desktop" -Name LogPixels -Value 120 -Type DWord -force New-ItemProperty -path registry::"HKU\$($Item.SID)\Control Panel\Desktop" -Name Win8DpiScaling -Value 1 -Type DWord -force ##################################################################### # Unload ntuser.dat IF ($item.SID -in $UnloadedHives.SID) { ### Garbage collection and closing of ntuser.dat ### [gc]::Collect() reg unload HKU\$($Item.SID) | Out-Null } } 

1 Comment

thanks for the answer, but that is not exactly what i am looking for

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.