Putting the screen working area into environment variables

I’ve found that if I type these two commands into powershell:

Add-Type -AssemblyName System.Windows.Forms

The response I get on my system is as follows:

BitsPerPixel : 32
Bounds       : {X=0,Y=0,Width=3840,Height=1080}
DeviceName   : \\.\DISPLAY1
Primary      : True
WorkingArea  : {X=0,Y=46,Width=3840,Height=1034}

BitsPerPixel : 32
Bounds       : {X=3840,Y=-158,Width=1920,Height=1200}
DeviceName   : \\.\DISPLAY2
Primary      : False
WorkingArea  : {X=3840,Y=-158,Width=1920,Height=1200}

What I would like to do is to write a script which puts the four numbers representing the working area of the primary display (0,46,3840,1080) in my example into 4 different environment variables that I could query from another application. Can anyone give me a suggestion about how this can be done. (I have no experience writting powershell scripts). Thanks ~Paul

Oops, I meant to say the four numbers (0,46,3840,1034) representing the working area. (I typed the last number incorrectly).

A simple approach would like below,

Add-Type -AssemblyName System.Windows.Forms
$DeviceName = 'DISPLAY2'
$ScreenDetail = [System.Windows.Forms.Screen]::AllScreens
$RequiredDisplay = $ScreenDetail | Where-Object -FilterScript {$_.DeviceName -match $DeviceName}
[System.Environment]::SetEnvironmentVariable('WorkingAreaX',$RequireDisplay.WorkingArea.X, [System.EnvironmentVariableTarget]::Machine)

# similar code for Y, Width and Height

Since the Environment variable scope is set to Machine, these variable wont be available in the same process and child processes. For that Process scope has to be used. If both are required, then Environment variable for each will have to be created per scope.

1 Like

I think you meant to say $DisplayName = ‘DISPLAY1’ since I wanted the primary display.
Also I think you have an extra single quote between Machine and the closing parenthesis. (It gave me an error message on that.)
With those changes, I executed the script in the powershell by typing .\WorkingArea.ps1
Then I typed “dir env:” and it displayed all the environment variables but not the 4 new ones that I had defined in my script. I also didn’t see them using the system applet in the windows control panel. I also tried changing Machine, to Process or User but in all those cases I did not see the environment variables when I typed “dir env:”. Do you have any guesses of what I am doing wrong?

My full script is shown below:

Add-Type -AssemblyName System.Windows.Forms
$DeviceName = 'DISPLAY1'
$ScreenDetail = [System.Windows.Forms.Screen]::AllScreens
$RequiredDisplay = $ScreenDetail | Where-Object -FilterScript {$_.DeviceName -match $DeviceName}
[System.Environment]::SetEnvironmentVariable('screenX',$RequireDisplay.WorkingArea.X, [System.EnvironmentVariableTarget]::Machine)
[System.Environment]::SetEnvironmentVariable('screenY',$RequireDisplay.WorkingArea.Y, [System.EnvironmentVariableTarget]::Machine)
[System.Environment]::SetEnvironmentVariable('screenW',$RequireDisplay.WorkingArea.Width, [System.EnvironmentVariableTarget]::Machine)
[System.Environment]::SetEnvironmentVariable('screenH',$RequireDisplay.WorkingArea.Height, [System.EnvironmentVariableTarget]::Machine)

Corrected by removing unwanted single quote.

If Machine scope is used, then You should be opening new PowerShell process to see them.
And the DeviceName variable value can be changed according to your preference.

If you need the environment variable in the same shell, then use Process scope.

This script simply did nothing. No environment variables were created. No errors, warnings, or anything. After much head scratching I found the problem. You defined the variable $RequiredDisplay but then when you referenced it to create the environment variable you spelled it differently ($RequreDisplay). Unfortunately I copied your script exactly. Once I fixed that problem, the script worked correctly. Despite that, I’m sure this would have taken me even longer without your help, so I thank you for that! ~Paul

1 Like

Now that I got the script working I find that it is useless for my intended purpose. I was planning on calling the script from another programming environment that doesn’t have the ability to get this display information on its own. I thought I could run a powershell script from this environment just like I can run batch scripts. But this won’t work because Windows doesn’t allow user powershell scripts to run by default like it does for batch scripts. I found I had to enter a command such as:

set-executionpolicy unrestricted -Scope CurrentUser

in a powershell administrator window before it would allow the script to run. I can’t really expect the users of my program to enter such an arcane command. Is there any workaround to this problem, or will I have to write a program in a language such as C# that would have access to the information I want?

I recommend to run

PowerShell /?

on a command line to learn how to run a PowerShell session. I recommend to take special notice of the parameter -ExecutionPolicy !!! :wink:

I was calling powershell using a command such as:

powershell -inputformat none -file scriptName.ps1

I tried changing this to:

powershell -inputformat none -file scriptName.ps1 -ExecutionPolicy Unrestricted

However the error message I got was the same:

File E:\mcode\misc\workingArea.ps1 cannot be loaded because running scripts is disabled on this system. For more  
information, see about_Execution_Policies at https:/go.microsoft.com/fwlink/?LinkID=135170. 
    + CategoryInfo          : SecurityError: (:) [], ParentContainsErrorRecordException 
    + FullyQualifiedErrorId : UnauthorizedAccess 

Am I using this parameter correctly?
This error went away when I changed the execution policy for a powershell window (as administrator).


If you read the error carefully, it says that to understand a lil more, its better to read Get-Help about_Execution_Policies. This will give you more help for sure.

I have read all that, but it doesn’t seem to suggest that the powershell will be useful to me. I’m not sure why the command I mentioned above that specified the ExecutionPolicy as unrestricted won’t run, but the help text suggests that this may have been overridden by a group policy. In any case I can’t expect my users to modify some arcane setting in the group policy editor or to run powershell with an equally arcane command to allow the script to run. It’s frustrating though, because you seem to know something that I don’t that may mean that the powershell isn’t as useless as it seems. But I don’t know what it is.

How about trying -ExecutionPolicy Bypass or you have already tried it ?

Are you sure there is no group policy? If you have a group policy users without administrative rights cannot overwrite this setting.

A bit off topic but you can try a batch file:

for /F "skip=1" %%a in ('wmic desktopmonitor get ScreenHeight /value') do set %%a
for /F "skip=1" %%a in ('wmic desktopmonitor get ScreenWidth /value') do set %%a

Olaf - you are probably correct in that the group policy is not allowing unsigned powershell scripts from running. But I didn’t set such a policy which implies that the policy is there by default or at least that it is very easy to create such a policy accidently perhaps when other software is installed. But if it happened to me, then it would probably happen to some of my users … which makes the powershell script a non-starter. There is no reason to force my users to use the group policy editor (most of whom won’t even know what that is) for something as benign as writing a text file to a folder known to have write permission. (I gave up on the environment variable idea, and I’m now using a simple text file.). It sounds like I might have to create a .exe file using C# or other language to create this text file. (I’ve never used C# so this isn’t going to be trivial for me.)

tonyd - no that is not off topic. A batch file would be a lot easier for me because having an exe file in a distributation that normally only contains source code will be problematic. Batch is a lot better because it is a text file and I know there are no default group policies preventing batch files from running. But your batch file just gives me the screen dimensions which are already easily available in my programming environment. What I need are the the coordinates of the working area … i.e. the portion of the screen that is not occupied by the taskbar. Is there any way to get this information using a batch file? It would be wonderful if there was a way to do that.

They are not there by default and they won’t be created accidently. Is your environment an enterprise environment? Are you the only administrator in this environment? What is it actually what you’re trying to do - not the environment variable thing … the big picture? I’d suspect we are having an

They aren’t allowed to do that anyway. Well … they shouldn’t be allowed.

My first thought on this topic was to get what you needed from WMI, hence the batch and WMIC. You may want to enter a blank “wmic /?” to see if there is anything you can query to get what you want. Sorry for not being any help.

Can you share details about your application that might help get an answer, programming language etc?