Manage window location using a script

GitHub

mattiasvdlbe/Windows/ManageAppLocation

Why?

We where asked to help with setting up the work desk of the operator of a new line which was being installed.
After talking to the people involved in the project, the operators and analysing what there exact requirements, we ended up suggesting 2 big 43″ 4k displays connected to 1 pc.

This made sure we had enough screen real estate to display all of the tools and applications which they need to do there job, but the default Windows window snapping system is insufficient.
The operator has more than 8 different windows, and some need to be shown bigger than others.

We could use FancyZones, which is part of Power Toys to customize where and how the different windows can be snapped in place.
However, if the user needs to snap all the different windows in place every time the pc is restarted, this would get really annoying.

We decided to check if we couldn’t achieve this with just a hotkey on the keyboard which calls a script.

After doing some research, I found the best and easiest way to achieve this currently is using a command line utility called NirCmd from NirSoft.

I would have preferred not having to use a 3rd party utility to achieve this, but this didn’t seem to be possible yet, or wasn’t as user friendly.
In the near future, we might be able to use the upcoming API exposed by the Windows UIAutomation platform, but this is only available at the moment if the Windows Insider Preview SDK is installed.

What?

Script in which we specify the size of specific windows, and where they need to be positioned on the screen.

Change the language of the users mailbox

A new employee started at the company I work for.
He speaks German, and our environment is set up in Dutch.

After creating and setting up his account, we noticed his mailbox remained in Dutch, even though we set the language everywhere we could in the GUI and AD to German (de-DE).
This included the changes I wrote about in this post:
https://www.mattiasvdl.be/display-language-in-hybrid-environment/

Outlook – Foldernames in Dutch while everything else in German

As everything is in German (web browser, Windows, Microsoft 365, …) except for his mailbox which was displayed in Dutch, I decided to user the Exchange Powershell module in order to check if I can find any language or regional settings which might be hidden in the UI.

And what do you know! That’s exactly what I found. A hidden setting in Exchange online which specifies the language of the mailbox.

Powershell ExchangeOnline module – MailboxRegionalConfiguration shows the hidden language setting

After changing the language here, you can force the folder names to be reset by starting Outlook using the “/resetfoldernames” argument.

Outlook.exe – reset foldernames

The foldernames should now be displayed in the language you specified using Powershell.


Below you can find the code I used:

# Install the ExchangeOnline module incase you haven't got the module yet:
Import-Module ExchangeOnlineManagement

# Connect to ExchangeOnline:
Connect-ExchangeOnline -UserPrincipalName %YourAdminUPN%

# Check what language is currently set for the user:
Get-MailboxRegionalConfiguration -Identity %UPNOfTheUserMailbox%

# Change the language for this mailbox:
Set-MailboxRegionalConfiguration -Identity %UPNOfTheUserMailbox% -Language %LanguageCode%

# Disconnect from ExchangeOnline:
Disconnect-ExchangeOnline

The language codes you can use can be found here:
[MS-OE376]: Part 4 Section 7.6.2.39, LCID (Locale ID) | Microsoft Learn

Package and Upload Intune Win32 app using .ps1 script

GitHub

mattiasvdlbe/MS Endpoint Manager/Apps/PackageAndUploadIntuneWin32AppUsingPs1Script

Why?

A couple of months ago, I needed to create a lot of Win32 apps.
As I knew these apps would have to be updated and repackaged quite a few times in the future, I decided it would be worth the effort to automate this process using a script.

The purpose of these apps was to create a shortcut under the Start Menu of the end user which points to a script placed under %PROGRAMDATA%.
When executing this script, a check was done to see if the end user is working in the office or remote.
If the end user works remotely, then the application is started in an RDS environment. Otherwise, the app gets started locally on his device.

This post is focussed on the deployment of Intune Win32 apps using a Powershell script, and as such doesn’t contain the code I mentioned above.

What?

  • PackageAndUploadIntuneWin32App.ps1
    This Powershell script contains all of the code to generate the 3 needed Powershell scripts, package the application and upload it to Intune.

The 3 Powershell scripts which need to be generated:
– App_MattiasVdl_Setup.ps1
This script is used to create the shortcut under the start menu, and copy the script, which is executed by the shortcut, to the correct location.
– App_MattiasVdl.ps1
This is the script which gets executed when a user clicks on the shortcut which was created under the Start Menu.
All logic which was in this script has been removed, and all it does now is display a message box.
– App_MattiasVdl_Detection.ps1
This script is used by Intune to detect whether or not the application has been correctly installed on the device.

To start off with, a lot of variables are declared which are later used in the application.

We specify an array which contains the different types of scripts which need to be created.

The script makes use of “template” scripts, in which there are strings of text that get replace by the correct values.
The location of these template scripts is defined in the variables.

We also specify in these variables what the name of the application needs to be, what icon to use and the log which should be used in Intune.

We use a foreach loop to generate the necessary scripts.

First we load the script into a variable, and save the output URL to a variable so we can use it later.

Next we modify the script which we loaded into a variable.
We replace all instanced of the variables we placed in the template (using the “{}” as a way to easily be able to replace the strings without replacing things which shouldn’t be replaced.

Then the modified script gets saved to the output URL which we saved to a variable earlier.

The script copies the icon over from the original location to the folder which will be be packaged and uploaded to InTune.

All necessary preparations have now been done and we’re ready to package the application.
This is done using the IntuneWinAppUtil.exe, which is also available on my Repository, but I recommend you download the latest version of this app from the original creator (microsoft/Microsoft-Win32-Content-Prep-Tool).

Now it’s time to upload the application to InTune.
First we set some of the variables which will be used.
Change the TenantID in line 106 “Connect-MSIntuneGraph” to your own TenantID.

In my example script I’m not setting any dependencies, supersedence or assignments.
These can all be added automatically, but in my case, I prefer to manually check up on the applications which are uploaded and assign them to the relevant groups manually.

  • App_Link_Application_Setup.ps1

This script contains the base code, which is edited by the main script, and is used to install the application script and shortcuts on the end-user device.

Note:
There are multiple ways of adding folders and files to your Start Menu.
Only for 1 user: %APPDATA%\Microsoft\Windows\Start Menu\Programs
For all users: %PROGRAMDATA%\Microsoft\Windows\Start Menu\Programs

Also keep in mind that the name of the shortcut can’t be the same of the name of the folder. If the name of the folder is identical to the name of the shortcut, then the folder will not be shown!

  • App_Link_Application.ps1

This is the script which will get executed when the end-user presses the shortcut which has been added in there Start Menu.

  • App_Link_Application_Detection.ps1

This is the detection script which reports back to Intune whether or not the applications has been installed correctly.

Note:
In order for a detection script to work properly, it needs to both exit with code 0 AND write something to STDOUT

Sources

Update User Data

GitHub

mattiasvdlbe/Active Directory/UpdateUserData

Why?

I had to make a bulk update of data for a list of users, and instead of opening each user profile one by one and changing the values, I decided to write a script which could do this in bulk for me. It saved me a lot of time and avoided typing and other user errors.
I only needed to make sure the input csv was set up correctly.

What?

I started of with an export of all necessary fields from the Active directory, made this a bit more readable for the people responsible for determining the data which needs to be updated, and provided the file to them for correction of the data.
When I received the file back, I made sure all necessary data was filled in, generated the necessary codes for the countries, and generate the .csv file this script needs to make the updates.

This script loads in the .csv file and loops over all users in the file and updates the necessary fields.

More information

  • The titles in the .csv file are the names used in AD.
    You can look these up in the “Attribute Editor” tab.
  • For the Country details:
    • “c” = 2-character ISO-3166 country code (ex.: BE)
    • “co” = the name of the country as a text string (ex.: Belgium)
    • “countryCode” = the country code for the user’s language of choice (ex.: 56)

List of ISO 3166 country codes – Wikipedia

  • In this script I only changed a couple of fields, as more where not required in this case.
    I also just cleared some attributes, without replacing them.
    You should be able to edit the code based on this example in case you need to edit more attributes.

Enable PrtScr Snipping Tool

GitHub

mattiasvdlbe/MS Endpoint Manager/Proactive Remediations/PR_U_EnablePrtScrSnippingTool

Why?

The Windows Snipping tool is a very useful tool to quickly make print screen of specific parts of your screen.

The ability to start the application by clicking on the print screen button on your keyboard instead of having to open the program manually can save you time and is just a big convenience.

In the windows settings, you can manually enable this setting, but I’ve created a script so this functionality can be pushed to the devices of the end users without manual action.
This saves me or the end user having to remember to turn this setting on after they start using a newly rolled out device.

What?

This script checks if this function is enabled.
In the settings of Windows, you can find this setting here:

Set Print screen button to open Screen Snipping Tool

In case this option isn’t enabled yet, the remediation is triggered which will enable this function.

It also creates a log with some text outputs which are specified in the script.
For this, it uses an implemented function called “Write-Log()”
If you want to use this script, don’t forget to change the log output path.

Time And Date Correction

GitHub

mattiasvdlbe/MS Endpoint Manager/Proactive Remediations/PR_S_TimeAndDateCorrection

Why?

Some time ago, we had some devices which were no longer running on the correct time.
On the devices in question the users didn’t have administrator permissions, so they couldn’t change the time and date themselves.

As the end users needed to be able to continue their work as soon as possible, and the issue wasn’t widespread, we decided to just create a small script to fix the issue.
The script shared in this post, is more advanced, and has more options.

If you want to use it, check if all things checked and set in this script are relevant in your case.

What?

This script does some checks to make sure the end user device is using the correct date and time.

Things the proactive remediation checks:

  • StartupType of the Windows Time Service is set to “Manual” (which is the default setting)
  • Windows Time Service is running
  • “Set the time automatically” is activated
  • Location use is allowed (Privacy setting).
    Location use needs to be allowed if you want to allow the system to automatically detect what time zone your currently in.
  • “Set the time zone automatically” is enabled
  • Compare NtpServer time and the local computer time.
    If there’s a difference of more than 15 seconds either way (ahead or behind)

In case any of these checks fails, the remediation gets triggered, which then puts the system back to our desired configuration.

It also creates a log with some text outputs which are specified in the script.
For this, it uses an implemented function called “Write-Log()”
If you want to use this script, don’t forget to change the log output path.

Other functions which are implemented: