Laurent Finet-Baron
Laurent Finet-Baron

Reputation: 461

Change "Windows font size (DPI)" in PowerShell?

I'm using a laptop at office (Windows 7) with a station and double screen and at home without station.

The point is I have to change text size each time I switch from station to standlone laptop, because the text size is too big on my double screen, but too small on my laptop screen.

To proceed: I right-click on desk screen, choose change resolution then "get text and other elements bigger or smaller" to choose 100%, 125%, etc... I need to restart my session to get the settings applied. (Note: I'm using a French system, and texts are not exactly the same on us version I suppose).

It's not very convenient so I'd like to automate this, perhaps with a PowerShell script.

Ideally the script may detect if I'm using laptop alone or station with its two screens). Plus, without session restart (I doubt this last point is feasible).

How do I get started? If this is possible.

Upvotes: 19

Views: 44634

Answers (9)

nevarDeath
nevarDeath

Reputation: 197

This is the most straightforward method I've found. I lightly modified the provided function so it's an easy copy/paste. It does not require any registry calls or anything. Simple and very effective.

You can call it like this

function Set-Scaling {
    # Posted by IanXue-MSFT on
    # https://learn.microsoft.com/en-us/answers/questions/197944/batch-file-or-tool-like-powertoy-to-change-the-res.html
    # $scaling = 0 : 100% (default)
    # $scaling = 1 : 125% 
    # $scaling = 2 : 150% 
    # $scaling = 3 : 175% 
    param($scaling)
    $source = @'
    [DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
    public static extern bool SystemParametersInfo(
                      uint uiAction,
                      uint uiParam,
                      uint pvParam,
                      uint fWinIni);
'@
    $apicall = Add-Type -MemberDefinition $source -Name WinAPICall -Namespace SystemParamInfo -PassThru
    $apicall::SystemParametersInfo(0x009F, $scaling, $null, 1) | Out-Null
}

Set-Scaling -scaling 0

Upvotes: 13

Cynomus
Cynomus

Reputation: 37

Love this Answer, anyone have any idea on how to set for a single display instead of all at the same time? I have 3 monitors, and this is a universal change.

Set-Scaling -scaling 0

function Set-Scaling {
    # Posted by IanXue-MSFT on
    # https://learn.microsoft.com/en-us/answers/questions/197944/batch-file-or-tool-like-powertoy-to-change-the-res.html
    # $scaling = 0 : 100% (default)
    # $scaling = 1 : 125% 
    # $scaling = 2 : 150% 
    # $scaling = 3 : 175% 
    param($scaling)
$source = @'
    [DllImport("user32.dll", EntryPoint = "SystemParametersInfo")]
    public static extern bool SystemParametersInfo(
                      uint uiAction,
                      uint uiParam,
                      uint pvParam,
                      uint fWinIni);
'@
    $apicall = Add-Type -MemberDefinition $source -Name WinAPICall -Namespace SystemParamInfo –PassThru
    $apicall::SystemParametersInfo(0x009F, $scaling, $null, 1) | Out-Null
    }

Upvotes: -1

Nimai
Nimai

Reputation: 783

By comparing the output of Get-ItemProperty -Path 'HKCU:\Control Panel\Desktop' before and after using the Windows GUI to set the scaling level, I found the following properties needed setting; worked for me:

cd 'HKCU:\Control Panel\Desktop'
Set-ItemProperty -Path . -Name LogPixels -Value 144
Set-ItemProperty -Path . -Name Win8DpiScaling -Value 1
Set-ItemProperty -Path . -Name FocusBorderHeight -Value 2
Set-ItemProperty -Path . -Name FocusBorderWidth -Value 2
Write-Host 'Sign out and sign back in again to see changes.'

Upvotes: 0

Helio Passarelli
Helio Passarelli

Reputation: 155

After much time, I can't find anything in google. Well, I made my own script:

$perfis = (Get-ChildItem Registry::HKEY_USERS\ | Where-Object {$_.Name -match "S-1"} | ForEach-Object {Get-ItemProperty "Registry::$_\Control Panel\Desktop" -Name "Win8DpiScaling" -ErrorAction SilentlyContinue}).PSPath
foreach ($_ in $perfis) {Set-ItemProperty -Path "Registry::$_" -Name "Win8DpiScaling" -Value 0}

$monitores = (Get-ChildItem Registry::HKEY_USERS\ | Where-Object {$_.Name -match "S-1"} | ForEach-Object {Get-ChildItem "Registry::$_\Control Panel\Desktop\PerMonitorSettings" -ErrorAction SilentlyContinue}).PSPath
foreach ($_ in $monitores) {Set-ItemProperty -Path "Registry::$_" -Name "DpiValue" -Value 0}

Upvotes: 1

Torben Schramme
Torben Schramme

Reputation: 2140

As supposed in the other answers, the setting under HKLM is not the correct place as the dpi scaling is a user defined setting. The correct registry key is HKCU:\Control Panel\Desktop with the value LogPixels.

More information about all DPI-related registry settings can be found in DPI-related APIs and registry settings.

I wrote a tiny PowerShell script that changes the DPI scaling depending on the current scaling and performs the user logoff, so I just have to execute the script when I put my device to a different monitor.

cd 'HKCU:\Control Panel\Desktop'
$val = Get-ItemProperty -Path . -Name "LogPixels"
if($val.LogPixels -ne 96)
{
    Write-Host 'Change to 100% / 96 dpi'
    Set-ItemProperty -Path . -Name LogPixels -Value 96
} else {
    Write-Host 'Change to 150% / 144 dpi'
    Set-ItemProperty -Path . -Name LogPixels -Value 144
}

logoff;exit

Upvotes: 8

Yooakim
Yooakim

Reputation: 1817

Sorry, I misread the question. I thought you wanted to control the PowerShell windows.

As already mentioned you could set the LogPixels setting in the registry, to see what the current setting is, try this:

Get-Item -Path Registry::'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontDPI' | Select-Object -ExpandProperty Property

If the LogPixels key is there it will show, you can create it if it does not exist:

Set-Item -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\FontDPI\LogPixels'

NB: You have to run this with privileges that allow you to manipulate the registry.

There is a good introduction to this over at TechNet.

Upvotes: 3

diallo Ramadane
diallo Ramadane

Reputation: 1

These simple steps worked for me:

  1. Download Win7AndW2K8R2-KB3191566-x64.ZIP from https://learn.microsoft.com/en-us/powershell/wmf/5.1/install-configure

  2. Unzip the file in tmp folder

  3. Open a Powershell command window as Administrator, go in tmp folder where file has been unzipped and execute the following commands :

    set-executionpolicy remotesigned .\Install-WMF5.1.ps1

Upvotes: -10

Eric Korb
Eric Korb

Reputation: 21

@Torben Schramme I found that I had to add one more ItemProperty Win8DpiScaling for this work. But, I don't find the "logoff; exit" function working - I still have to do it manually.

cd 'HKCU:\Control Panel\Desktop'
$val = Get-ItemProperty -Path . -Name "LogPixels"
if($val.LogPixels -ne 96)
{
     Write-Host 'Change to 100% / 96 dpi'
     Set-ItemProperty -Path . -Name LogPixels -Value 96
     Set-ItemProperty -Path . -Name Win8DpiScaling 0
} else {
     Write-Host 'Change to 150% / 144 dpi'
     Set-ItemProperty -Path . -Name LogPixels -Value 144
     Set-ItemProperty -Path . -Name Win8DpiScaling 1
}
logoff;exit

Upvotes: 1

Joey
Joey

Reputation: 354566

Apparently you can set the LogPixels property of

HKLM:/Software/Microsoft/Windows NT/CurrentVersion/FontDPI

which is reiterated in a lot of places around the net. However, I got the impression that dpi was a user setting which makes no sense to have under HKLM.

Upvotes: 5

Related Questions