# 05-OfficeShortcuts.ps1 - Public desktop + Default User Start Menu shortcuts for # the core Office apps (Excel, Word, PowerPoint). # # Only runs if Office is actually installed - self-detects via EXE existence so it # silently no-ops on PC types whose ppkg didn't include Office (Display kiosks, # Wax/Trace, etc.). Office Click-to-Run installs the binaries but doesn't create # desktop shortcuts; this script fills that gap. # # Shortcuts land in two places: # - C:\Users\Public\Desktop\ - visible to all users immediately # - C:\Users\Default\AppData\Roaming\Microsoft\Windows\Start Menu\Programs\ # - inherited by every NEW user profile # (Azure AD logons after the device is # enrolled) # # Idempotent: overwrites existing .lnk files each run. $officeApps = @( @{ Exe = 'EXCEL.EXE'; Name = 'Excel' } @{ Exe = 'WINWORD.EXE'; Name = 'Word' } @{ Exe = 'POWERPNT.EXE'; Name = 'PowerPoint' } ) # Office binary location varies by install type and version: # - Office 2019+ / M365 / LTSC Click-to-Run: \Microsoft Office\root\Office16\ # - Office 2016 MSI (legacy): \Microsoft Office\Office16\ (no root\) # - Office 2013 MSI: \Microsoft Office\Office15\ # - x86 Office on 64-bit Windows: Program Files (x86)\... # The standard ShopFloor Office ppkg is x86 Click-to-Run so normal case # is "Program Files (x86)\Microsoft Office\root\Office16\EXCEL.EXE", but # we check all variants so the script works across SKUs. $officeSearchRoots = @( 'C:\Program Files\Microsoft Office\root\Office16', 'C:\Program Files (x86)\Microsoft Office\root\Office16', 'C:\Program Files\Microsoft Office\Office16', 'C:\Program Files (x86)\Microsoft Office\Office16', 'C:\Program Files\Microsoft Office\Office15', 'C:\Program Files (x86)\Microsoft Office\Office15' ) $officeRoot = $null foreach ($base in $officeSearchRoots) { if (Test-Path (Join-Path $base 'EXCEL.EXE')) { $officeRoot = $base break } } if (-not $officeRoot) { Write-Host "No Office install detected - skipping shortcut creation." Write-Host "Searched:" foreach ($p in $officeSearchRoots) { $hit = if (Test-Path $p) { "(dir exists)" } else { "(missing)" } Write-Host " $p $hit" } exit 0 } Write-Host "Office detected at: $officeRoot" $publicDesktop = 'C:\Users\Public\Desktop' $defaultStart = 'C:\Users\Default\AppData\Roaming\Microsoft\Windows\Start Menu\Programs' if (-not (Test-Path $defaultStart)) { New-Item -Path $defaultStart -ItemType Directory -Force | Out-Null } $shell = New-Object -ComObject WScript.Shell foreach ($app in $officeApps) { $exePath = Join-Path $officeRoot $app.Exe if (-not (Test-Path $exePath)) { Write-Warning "$($app.Name) EXE not found at $exePath - skipping." continue } foreach ($dest in @($publicDesktop, $defaultStart)) { $lnkPath = Join-Path $dest "$($app.Name).lnk" try { $sc = $shell.CreateShortcut($lnkPath) $sc.TargetPath = $exePath $sc.WorkingDirectory = $officeRoot $sc.IconLocation = "$exePath,0" $sc.Save() Write-Host " $($app.Name) -> $lnkPath" } catch { Write-Warning "Failed to create $lnkPath : $($_.Exception.Message)" } } } [System.Runtime.InteropServices.Marshal]::ReleaseComObject($shell) | Out-Null Write-Host "Office shortcuts created." exit 0