Skip to content

Commit a9c9dda

Browse files
authored
Merge pull request #2292 from microsoft/OutlookScript
New script for Outlook added to CSS-Exchange
2 parents a4d3f08 + 33551e2 commit a9c9dda

File tree

3 files changed

+324
-0
lines changed

3 files changed

+324
-0
lines changed

Outlook/Update-OutlookLink.ps1

+291
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
# Copyright (c) Microsoft Corporation.
2+
# Licensed under the MIT License.
3+
4+
[CmdletBinding()]
5+
param(
6+
[string]$ComputerName = $env:COMPUTERNAME
7+
)
8+
9+
. $PSScriptRoot\..\Shared\Confirm-Administrator.ps1
10+
. $PSScriptRoot\..\Shared\Invoke-ScriptBlockHandler.ps1
11+
12+
# Define the lookup table for translations of "classic"
13+
#cspell:disable
14+
$translations = @{
15+
"af-za" = "klassiek"
16+
"sq-al" = "klasik"
17+
"am-et" = "ነባር"
18+
"ar-sa" = "كلاسيكي"
19+
"az-latn-az" = "klassik"
20+
"eu-es" = "klasikoa"
21+
"bg-bg" = "класическа версия"
22+
"ca-es" = "clàssic"
23+
"hr-hr" = "klasična verzija"
24+
"cs-cz" = "klasický"
25+
"da-dk" = "klassisk"
26+
"nl-nl" = "klassieke versie"
27+
"en-us" = "classic"
28+
"en-gb" = "classic"
29+
"et-ee" = "klassikaline"
30+
"fil-ph" = "classic"
31+
"fi-fi" = "perinteinen"
32+
"fr-fr" = "classique"
33+
"fr-ca" = "classique"
34+
"gl-es" = "clásico"
35+
"ka-ge" = "კლასიკური"
36+
"de-de" = "klassisch"
37+
"el-gr" = "κλασικό"
38+
"gu-in" = "ક્લાસિક"
39+
"he-il" = "קלאסי"
40+
"hi-in" = "क्लासिक"
41+
"hu-hu" = "klasszikus"
42+
"is-is" = "sígilt"
43+
"id-id" = "klasik"
44+
"it-it" = "versione classica"
45+
"ja-jp" = "クラシック"
46+
"kn-in" = "ಕ್ಲಾಸಿಕ್"
47+
"kk-kz" = "классикалық"
48+
"km-kh" = "ក្លាស៊ីក"
49+
"kok-in" = "क्लासीक"
50+
"ko-kr" = "클래식"
51+
"lo-la" = "ຄລາສສິກ"
52+
"lv-lv" = "klasiskā versija"
53+
"lt-lt" = "klasikinė"
54+
"mk-mk" = "класична верзија"
55+
"ml-in" = "ക്ലാസിക്"
56+
"mt-mt" = "klassiku"
57+
"mr-in" = "क्लासिक"
58+
"or-in" = "କ୍ଲାସିକ୍"
59+
"fa-ir" = "کلاسیک"
60+
"pl-pl" = "klasyczny"
61+
"pt-pt" = "clássico"
62+
"ro-ro" = "clasic"
63+
"ru-ru" = "классическая версия"
64+
"gd-gb" = "clasaigeach"
65+
"sr-cyrl-ba" = "класични"
66+
"sk-sk" = "klasická verzia"
67+
"sl-si" = "klasična različica"
68+
"es-es" = "clásico"
69+
"es-mx" = "clásico"
70+
"sv-se" = "klassisk"
71+
"ta-in" = "கிளாசிக்"
72+
"tt-ru" = "классик"
73+
"te-in" = "క్లాసిక్"
74+
"th-th" = "คลาสสิก"
75+
"tr-tr" = "klasik"
76+
"uk-ua" = "класична версія"
77+
"ur-pk" = "کلاسک"
78+
"ug-cn" = "كىلاسسىك"
79+
"vi-vn" = "phiên bản cũ"
80+
"cy-gb" = "clasurol"
81+
# General language codes
82+
"af" = "klassiek"
83+
"sq" = "klasik"
84+
"am" = "ነባር"
85+
"ar" = "كلاسيكي"
86+
"az" = "klassik"
87+
"eu" = "klasikoa"
88+
"bg" = "класическа версия"
89+
"ca" = "clàssic"
90+
"hr" = "klasična verzija"
91+
"cs" = "klasický"
92+
"da" = "klassisk"
93+
"nl" = "klassieke versie"
94+
"en" = "classic"
95+
"et" = "klassikaline"
96+
"fil" = "classic"
97+
"fi" = "perinteinen"
98+
"fr" = "classique"
99+
"gl" = "clásico"
100+
"ka" = "კლასიკური"
101+
"de" = "klassisch"
102+
"el" = "κλασικό"
103+
"gu" = "ક્લાસિક"
104+
"he" = "קלאסי"
105+
"hi" = "क्लासिक"
106+
"hu" = "klasszikus"
107+
"is" = "sígilt"
108+
"id" = "klasik"
109+
"it" = "versione classica"
110+
"ja" = "クラシック"
111+
"kn" = "ಕ್ಲಾಸಿಕ್"
112+
"kk" = "классикалық"
113+
"km" = "ក្លាស៊ីក"
114+
"kok" = "क्लासीक"
115+
"ko" = "클래식"
116+
"lo" = "ຄລາສສິກ"
117+
"lv" = "klasiskā versija"
118+
"lt" = "klasikinė"
119+
"mk" = "класична верзија"
120+
"ml" = "ക്ലാസിക്"
121+
"mt" = "klassiku"
122+
"mr" = "क्लासिक"
123+
"or" = "କ୍ଲାସିକ୍"
124+
"fa" = "کلاسیک"
125+
"pl" = "klasyczny"
126+
"pt" = "clássico"
127+
"ro" = "clasic"
128+
"ru" = "классическая версия"
129+
"gd" = "clasaigeach"
130+
"sr" = "класични"
131+
"sk" = "klasická verzia"
132+
"sl" = "klasična različica"
133+
"es" = "clásico"
134+
"sv" = "klassisk"
135+
"ta" = "கிளாசிக்"
136+
"tt" = "классик"
137+
"te" = "క్లాసిక్"
138+
"th" = "คลาสสิก"
139+
"tr" = "klasik"
140+
"uk" = "класична версія"
141+
"ur" = "کلاسک"
142+
"ug" = "كىلاسسىك"
143+
"vi" = "phiên bản cũ"
144+
"cy" = "clasurol"
145+
}
146+
#cspell:enable
147+
148+
if (-not (Confirm-Administrator)) {
149+
Write-Error "This script is not running with elevated privileges. Exiting script. Please run the script with elevated privileges." -ErrorAction Stop
150+
}
151+
152+
$scriptBlock = {
153+
# Function to get the Office Install Language
154+
function Get-OfficeInstallLanguage {
155+
try {
156+
# Define the registry path for Office
157+
$officeRegistryPath = "HKLM:\SOFTWARE\Microsoft\Office\ClickToRun\Configuration"
158+
159+
# Get the Office Install Language from the registry
160+
$installLanguage = Get-ItemProperty -Path $officeRegistryPath -Name "ClientCulture" | Select-Object -ExpandProperty ClientCulture
161+
162+
if ($installLanguage) {
163+
return $installLanguage.ToLower()
164+
} else {
165+
Write-Host "Office Install Language not found. Defaulting to en-us."
166+
return "en-us"
167+
}
168+
} catch {
169+
Write-Host "Error retrieving Office Install Language: $_. Defaulting to en-us." -ForegroundColor Red
170+
return "en-us"
171+
}
172+
}
173+
174+
# Function to get the translation for "classic"
175+
function Get-Translation {
176+
param (
177+
[string]$languageCode
178+
)
179+
180+
# Try to find the full language code first
181+
if ($translations.ContainsKey($languageCode)) {
182+
return $translations[$languageCode]
183+
} else {
184+
# If not found, try to find the general language code (e.g., "en" for "en-gb")
185+
$generalLanguageCode = $languageCode.Split('-')[0]
186+
if ($translations.ContainsKey($generalLanguageCode)) {
187+
return $translations[$generalLanguageCode]
188+
} else {
189+
Write-Host "Translation for 'classic' not found for language $languageCode. Using default translation: classic."
190+
return "classic"
191+
}
192+
}
193+
}
194+
195+
# Function to rename .lnk files
196+
function Rename-OutlookLnkFiles {
197+
param (
198+
[string[]]$directories,
199+
[string]$translation,
200+
[ref]$renamedFiles,
201+
[ref]$failedFiles
202+
)
203+
204+
foreach ($directory in $directories) {
205+
try {
206+
# Search for all .lnk files that point to Outlook.exe and have the name "Outlook" or "Microsoft Outlook"
207+
$lnkFiles = Get-ChildItem -Path $directory -Filter "*.lnk" -Recurse -ErrorAction SilentlyContinue | Where-Object {
208+
($_.Name -eq "Outlook.lnk" -or $_.Name -eq "Microsoft Outlook.lnk") -and
209+
(Select-String -Path $_.FullName -Pattern "Outlook.exe" -Quiet)
210+
}
211+
212+
# Rename the .lnk files
213+
foreach ($lnkFile in $lnkFiles) {
214+
try {
215+
$newName = if ($lnkFile.Name -eq "Outlook.lnk") {
216+
$lnkFile.DirectoryName + "\Outlook ($translation).lnk"
217+
} else {
218+
$lnkFile.DirectoryName + "\Microsoft Outlook ($translation).lnk"
219+
}
220+
Rename-Item -Path $lnkFile.FullName -NewName $newName -ErrorAction Stop
221+
$renamedFiles.Value += "$($lnkFile.FullName) -> $newName`n"
222+
} catch {
223+
Write-Host "Error renaming file $($lnkFile.FullName): $_" -ForegroundColor Red
224+
$failedFiles.Value += "$($lnkFile.FullName)`n"
225+
}
226+
}
227+
} catch {
228+
Write-Host "Error searching for .lnk files in directory $directory : $_" -ForegroundColor Red
229+
}
230+
}
231+
}
232+
233+
# Get the Office Install Language
234+
$officeLanguage = Get-OfficeInstallLanguage
235+
236+
# Get the translation for "classic" based on the Office Install Language
237+
$translation = Get-Translation -languageCode $officeLanguage
238+
239+
if ($translation) {
240+
# Define the directories to search using the current user's environment settings
241+
$directories = New-Object System.Collections.Generic.List[string]
242+
$directories.Add("$env:ProgramData\Microsoft\Windows\Start Menu\Programs")
243+
244+
$profiles = Get-CimInstance -ClassName Win32_UserProfile -ErrorAction Stop | Where-Object { $_.Special -eq $false }
245+
246+
if ($null -eq $profiles) {
247+
Write-Host "Failed to find the user profiles on the computer $env:COMPUTERNAME. Stopping the script."
248+
return
249+
}
250+
251+
foreach ($profile in $profiles) {
252+
$localPath = $profile.LocalPath
253+
if ($null -ne $localPath) {
254+
$directories.Add("$localPath\AppData\Roaming\Microsoft\Internet Explorer\Quick Launch")
255+
$directories.Add("$localPath\AppData\Roaming\Microsoft\Windows\Start Menu\Programs")
256+
}
257+
}
258+
259+
# Initialize variables to store the summary of renamed and failed files
260+
$renamedFiles = [ref] ""
261+
$failedFiles = [ref] ""
262+
263+
# Rename .lnk files in the specified directories
264+
Rename-OutlookLnkFiles -directories $directories -translation $translation -renamedFiles $renamedFiles -failedFiles $failedFiles
265+
266+
# Output the summary of renamed files if there are any
267+
if ($renamedFiles.Value) {
268+
Write-Host ""
269+
Write-Host "Summary of renamed .lnk files:"
270+
Write-Host $renamedFiles.Value
271+
}
272+
273+
# Output the summary of failed files if there are any
274+
if ($failedFiles.Value) {
275+
Write-Host ""
276+
Write-Host "Summary of .lnk files that failed to be renamed:"
277+
Write-Host $failedFiles.Value
278+
return
279+
}
280+
281+
# Output message if no files were renamed and no errors occurred
282+
if (-not $renamedFiles.Value -and -not $failedFiles.Value) {
283+
Write-Host "No files were renamed and no errors occurred. Nothing changed."
284+
}
285+
} else {
286+
Write-Host "Translation for 'classic' not found for language $officeLanguage."
287+
return
288+
}
289+
}
290+
291+
Invoke-ScriptBlockHandler -ComputerName $ComputerName -ScriptBlock $scriptBlock

docs/Outlook/Update-OutlookLink.md

+31
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
# Update-OutlookLink
2+
3+
Download the latest release: [Update-OutlookLink.ps1](https://github.com/microsoft/CSS-Exchange/releases/latest/download/Update-OutlookLink.ps1)
4+
5+
## Usage
6+
7+
Starting in July 2024, Microsoft changed the app name of Outlook for Windows as it appears in the Start menu from "Outlook" to "Outlook (classic)". This change became available starting in classic Outlook version 2407 and higher. Additional information is available for Tenant Admins in the M365 Service Health Dashboard in reference to message center post MC803006 and on [support.microsoft.com](https://support.microsoft.com/office/outlook-icon-on-the-start-menu-is-not-updated-to-outlook-classic-8e10e5c7-a33d-4c7e-8ca3-213fba1eff10).
8+
9+
The PowerShell Script will update the icon in both %ProgramData% and %AppData% automatically if needed. This makes it an option to run before updating to Office version 2407+.
10+
11+
PowerShell Script Options:
12+
13+
```powershell
14+
.\Update-OutlookLink.ps1
15+
```
16+
17+
If the user is not running elevated, it will warn them and ask if they want to continue.
18+
19+
It will attempt to lookup the users install language to use the correct translation of "classic".
20+
21+
After it runs it will describe what it did:
22+
23+
List of successful renames
24+
25+
List of unsuccessful renames
26+
27+
If you want to run this on a remote computer on the local network, you can use the following command:
28+
29+
```powershell
30+
.\Update-OutlookLink.ps1 -ComputerName <ComputerName>
31+
```

mkdocs.yml

+2
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,8 @@ nav:
8989
- Test-MailboxExtendedProperty: M365/Test-MailboxExtendedProperty.md
9090
- Search-MailboxExtendedProperty: M365/Search-MailboxExtendedProperty.md
9191
- Remove-MailboxExtendedProperty: M365/Remove-MailboxExtendedProperty.md
92+
- Outlook:
93+
-Update-OutlookLink: Outlook/Update-OutlookLink.md
9294
- Performance:
9395
- ExPerfWiz: Performance/ExPerfWiz.md
9496
- ExPerfAnalyzer: Performance/ExPerfAnalyzer.md

0 commit comments

Comments
 (0)