Created
October 18, 2019 03:47
-
-
Save billdeitrick/d3fa0b7657927768a27c01aaba435e0a to your computer and use it in GitHub Desktop.
An ExamView installation PowerShell script. Demonstrates symlinking data directories in %ProgramFiles(x86)% to user's OneDrive, and a few other workarounds.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Script Variables | |
$LOGGING_SUBDIR = "custom_deploy\logs" | |
# Setup logging environment | |
## Make directory if it doesn't exist | |
$log_dir = ($env:ProgramData + "\" + $LOGGING_SUBDIR) | |
$log_path = ($log_dir + "\examview_install.log") | |
if (! (Test-Path -Path $log_dir)) { | |
$result = New-Item -Path $log_dir -ItemType Directory | |
} | |
## Define reusable logging function | |
function Write-CustomLog { | |
param( | |
[Parameter(Mandatory=$true)] | |
[ValidateNotNull()] | |
[ValidateSet("Debug", "Error", "Info")] | |
[String] | |
$Level, | |
[Parameter(Mandatory=$true)] | |
[ValidateNotNull()] | |
[String] | |
$Message | |
) | |
Add-Content -Path $log_path -Value ("$Level >> " + (Get-Date).ToString() + " >> $Message") | |
} | |
# Log script start | |
Write-CustomLog -Level Info -Message "Starting ExamView primary installation script." | |
# Get profile path for the logged in user (fail install if more than one user logged in) | |
## Get all owning user names of all running explorer.exe instances | |
$explorers = (Get-WMIObject -Class Win32_Process -Filter 'Name="explorer.exe"') | |
$owners = New-Object System.Collections.Generic.HashSet[String] | |
foreach($instance in $explorers) { | |
$result = $owners.Add($instance.GetOwner().User) | |
} | |
## Fail if more than one user logged in, because we don't know where to point symlinks (who is the primary user?) | |
if ($owners.Count -ne 1) { | |
Write-CustomLog -Level Error -Message ("Found " + $owners.Count + " users logged in. Cannot continue; quitting installation.") | |
exit 1 | |
} | |
## We have a good username; let's get SID | |
$username = $owners[0] | |
$username = $username.Replace('.', '') | |
$user = New-Object System.Security.Principal.NTAccount("azuread\$username") | |
$sid = $user.Translate([System.Security.Principal.SecurityIdentifier]).Value | |
## We have a SID; let's get a profile path | |
$profile_path = (Get-ChildItem 'HKLM:\Software\Microsoft\Windows NT\CurrentVersion\ProfileList' | Where-Object {$_.Name -like "*$sid"}).GetValue('ProfileImagePath') | |
## Finally, we know the documents folder path on OneDrive | |
$od_documents_path = "$profile_path\OneDrive - [Company Name]\Documents" | |
Write-CustomLog -Level Info -Message "Calculated OneDrive path to use for the installation: '$od_documents_path'" | |
## Fail if the documents path isn't good | |
if (!(Test-Path -Path $od_documents_path)) { | |
Write-CustomLog -Level Error -Message "Calculated OneDrive path is no good. Quitting installation." | |
exit 1 | |
} | |
# We know we have a good documents folder path to which we should be able to create a symlink | |
# for ExamView data. Let's install ExamView and remove superfluous stuff. | |
Write-CustomLog -Level Info -Message "Running the ExamView installer." | |
## Silent ExamView Install | |
Start-Process "$PSScriptRoot\Setup.exe" -Wait -ArgumentList "/S /v/qn" | |
Write-CustomLog -Level Info -Message "Finished running the ExamView installer." | |
## Remove TestPlayer Desktop Shortcut (don't think this will ever be used) | |
Remove-Item -Path "C:\Users\Public\Desktop\ExamView TestPlayer.lnk" -Force | |
## Uninstall course-specific content bundled with the installer we're using | |
Start-Process msiexec.exe -Wait -ArgumentList "/x {65345e0b-f58a-490d-aa64-f392ade8219b} /q" | |
# Setup symlinks for ExamView Data | |
Write-CustomLog -Level Info -Message "Creating folder SymLinks for ExamView content." | |
## These are the folders we want | |
$symlink_folders = @( | |
"Banks", | |
"Classes", | |
"Tests" | |
) | |
## Create desired directories if they don't exist | |
$ev_base_path = "$od_documents_path\ExamView Content" | |
foreach($folder in $symlink_folders) { | |
$path = "$ev_base_path\$folder" | |
if(!(Test-Path -Path $path)) { | |
Write-CustomLog -Level Info -Message "Creating new path on OneDrive destination (existing path was not found): '$path'" | |
$result = New-Item -Path $path -ItemType Directory | |
} | |
} | |
## Setup the symlinks | |
$program_path = (${env:ProgramFiles(x86)} + "\eInstruction\ExamView") | |
foreach($folder in $symlink_folders) { | |
Write-CustomLog -Level Info -Message "Creating symlink for folder '$folder'" | |
# Remove existing folder in %programfiles(x86)% | |
$result = Remove-Item -Path "$program_path\$folder" -Force -Recurse | |
# Setup the junction | |
$result = New-Item -ItemType SymbolicLink -Path "$program_Path\$folder" -Target "$ev_base_path\$folder" -Force | |
} | |
Write-CustomLog -Level Info -Message "ExamView primary installation script finished." |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment