-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathScriptLaunch.ps1
More file actions
171 lines (150 loc) · 8.9 KB
/
ScriptLaunch.ps1
File metadata and controls
171 lines (150 loc) · 8.9 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
Param(
[Parameter(Mandatory=$True,Position=0)]
[string]$ScriptFile,
[Parameter(Mandatory=$False)]
[switch]$BypassAdminHook,
[Parameter(Mandatory=$False)]
[string]$Arguments=""
)
Set-StrictMode -Version Latest
$ErrorActionPreference = "Stop"
Set-Variable -Option Constant -Name SlEventLog -Value "ScriptLaunch"
Set-Variable -Option Constant -Name SlEventAppSource -Value "ScriptLaunch"
Set-Variable -Option Constant -Name EvlInvoked -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1000; "EntryType"="Information"}
Set-Variable -Option Constant -Name EvlUserNoApp -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1001; "EntryType"="Error"}
Set-Variable -Option Constant -Name EvlNoApp -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1002; "EntryType"="Error"}
Set-Variable -Option Constant -Name EvlPreCache -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1003; "EntryType"="Information"}
Set-Variable -Option Constant -Name EvlPostCache -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1004; "EntryType"="Information"}
Set-Variable -Option Constant -Name EvlFailCache -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1005; "EntryType"="Error"}
Set-Variable -Option Constant -Name EvlNoScript -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1006; "EntryType"="Error"}
Set-Variable -Option Constant -Name EvlScriptStart -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1007; "EntryType"="Information"}
Set-Variable -Option Constant -Name EvlScriptDone -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1008; "EntryType"="Information"}
Set-Variable -Option Constant -Name EvlScriptError -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1009; "EntryType"="Error"}
Set-Variable -Option Constant -Name EvlGetAppxError -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1010; "EntryType"="Warning"}
Set-Variable -Option Constant -Name EvlNoAppRetry -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1011; "EntryType"="Warning"}
Set-Variable -Option Constant -Name EvlNoCandidates -Value @{"LogName"=$SlEventLog; "Source"=$SlEventAppSource; "EventId"=1012; "EntryType"="Warning"}
# Log the details of our invocation
$elevatedString = "non-elevated"
$isElevated = $false
if (([Security.Principal.WindowsPrincipal] [Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole(`
[Security.Principal.WindowsBuiltInRole] "Administrator")) {
$elevatedString = "elevated"
$isElevated = $true
}
$user = ([System.Security.Principal.WindowsIdentity]::GetCurrent().Name)
Write-EventLog @EvlInvoked -Message ("Invoked as {0}, {1}: {2} {3}" -f $user, $elevatedString, $MyInvocation.Line, $ScriptFile)
# Locate the requested script
$SystemDrive = (Join-Path ${env:SystemDrive} "")
$adminPath = ([System.IO.Path]::Combine($SystemDrive, "Rigel", "AdminHookScripts", $ScriptFile))
$launchPath = $null
function Get-SrsPackageFromCandidate
{
param(
[parameter(Mandatory=$true)]
[AllowNull()]
$SrsPackageCandidate
)
if ($SrsPackageCandidate -eq $null) {
Write-EventLog @EvlNoCandidates -Message ("No candidates to select from; returning nothing. User: {0}, File: {1}" -f $script:user, $script:ScriptFile)
return $null
}
$SrsPackage = $null
$SrsPackageCandidate = ($SrsPackageCandidate `
| Where-Object { $_ -ne $null -and !([string]::IsNullOrEmpty($_.InstallLocation)) } `
| ForEach-Object { [PsCustomObject]@{"Version"=([Version]$_.Version); "Package"=$_} } `
| Sort-Object -Property Version -Descending `
| Select-Object -First 1)
if ($SrsPackageCandidate -ne $null) {
$SrsPackage = $SrsPackageCandidate.Package
}
return $SrsPackage
}
if (!$BypassAdminHook -and (Test-Path $adminPath)) {
$launchPath = $adminPath
} else {
$SrsPackage = $null
$SrsPackageCandidate = $null
$retrycount = 0
do {
try {
if ($isElevated -eq $false) {
# We are a non-elevated user -- we can only check if the package is installed for us.
$SrsPackageCandidate = (Get-AppxPackage -Name Microsoft.SkypeRoomSystem)
}
else {
# We're elevated. Specifically look at the version of the app installed for the Skype user with priority.
$SrsPackageCandidate = (Get-AppxPackage -Name Microsoft.SkypeRoomSystem -User Skype)
}
} catch {
# Certain builds of Windows can get into a state where Get-AppxPackage
# can throw an exception in certain circumstances. Log when this occurs and retry
$Exception = ($_.Exception|Out-String)
Write-EventLog @EvlGetAppxError -Message ("Get-AppxPackage threw an exception: $Exception. User: $user, File: $ScriptFile")
}
$SrsPackage = (Get-SrsPackageFromCandidate $SrsPackageCandidate)
# When running the scheduled task that launches the Logon.ps1 script as NT AUTHORITY\SYSTEM
# when the Skype user logs on, the app sometimes registers as not installed for any user.
# Add this retry logic to try and work around these instances, since the problem seems only
# to occur for certain machines at this specific time.
if($SrsPackage -eq $null) {
Write-EventLog @EvlNoAppRetry -Message ("Skype Room System app not installed. Waiting and retrying. User: $user, File: $ScriptFile")
Start-Sleep -Seconds 30
}
} while ($SrsPackage -eq $null -and ++$retrycount -lt 4)
if ($SrsPackage -eq $null -and $isElevated -eq $true) {
# Try finding the scripts installed for any other user.
# CollectSrsV2Logs.ps1 requires the scripts to gather logs.
try {
$SrsPackage = (Get-SrsPackageFromCandidate (Get-AppxPackage Microsoft.SkypeRoomSystem -AllUsers))
} catch {
}
$retrycount++
}
if ($SrsPackage -eq $null) {
if ($isElevated -eq $true) {
Write-EventLog @EvlNoApp -Message ("Cannot proceed; no override, and Skype Room System app not installed. User: $user, File: $ScriptFile")
}
else {
Write-EventLog @EvlUserNoApp -Message ("Cannot proceed; non-elevated user does not have app installed. User: $user, File: $ScriptFile")
}
Exit
}
# Select the first non-null value from InstallLocation.
#
# Some Windows implementations of InstallLocation emit an array with a leading
# $null value, which Path::Combine interprets as joining a space to the front
# the path (which messes up the path's validity). This works around that issue.
#
# V3 of PowerShell apparently changed how $null is handled in the pipeline --
# try to be very specific about non-null, non-empty values, and picking only the
# first one (if more than one happen to ever exist).
$installLocation = $SrsPackage.InstallLocation |? { ![string]::IsNullOrEmpty($_) } | Select-Object -First 1
$appPath = ([System.IO.Path]::Combine($installLocation, "Scripts"))
$cachePath = ([System.IO.Path]::Combine(${env:UserProfile}, "ScriptLaunchCache"))
$targetScript = ([System.IO.Path]::Combine($cachePath, $ScriptFile))
Write-EventLog @EvlPreCache -Message ("Updating script cache at $cachePath with contents at $appPath. User: $user, File: $ScriptFile")
try {
robocopy "$appPath" "$cachePath" /R:12 /W:10 /MIR
if ($LastExitCode -ge 8) { throw "Robocopy exited with an error code $LastExitCode." }
Write-EventLog @EvlPostCache -Message ("Script cache updated at $cachePath. User: $user, File: $ScriptFile")
} catch {
$Exception = ($_.Exception|Out-String)
Write-EventLog @EvlFailCache -Message ("Failed to update script cache at ${cachePath}: $Exception. User: $user, File: $ScriptFile")
Exit
}
if (!(Test-Path $targetScript)) {
Write-EventLog @EvlNoScript -Message ("Cannot proceed; no override, and script does not exist in the app: $targetScript. User: $user, File: $ScriptFile")
Exit
}
$launchPath = $targetScript
}
# Execute the located script
Write-EventLog @EvlScriptStart -Message ("Starting $launchPath $Arguments. User: $user, File: $ScriptFile")
try {
powershell.exe -executionpolicy unrestricted "$launchPath" $Arguments
schtasks /run /tn "MTRLock1"
if ($LastExitCode -ne 0) { throw "Script exited with an error code $LastExitCode." }
Write-EventLog @EvlScriptDone -Message ("Teams starting MTR Script completed: $launchPath. User: $user, File: $ScriptFile Args $Arguments")
} catch {
Write-EventLog @EvlScriptError -Message ("$_.Exception|Out-String. User: $user, File: $ScriptFile")
}