-
Notifications
You must be signed in to change notification settings - Fork 7
/
Install-CMTrace.ps1
184 lines (159 loc) · 6.36 KB
/
Install-CMTrace.ps1
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
172
173
174
175
176
177
178
179
180
181
182
183
184
<#
.SYNOPSIS
Download and Install the Microsoft ConfigMgr 2012 Toolkit R2
.DESCRIPTION
This script will download and install the Microsoft ConfigMgr 2012 Toolkit R2.
The intention was to use the scrtipt for Intune managed devices to easily read log files in the absence of the ConfigMgr client and C:\Windows\CCM\CMTrace.exe
.EXAMPLE
.\Install-CMTrace.exe
.NOTES
FileName: Install-CMTrace.ps1
Author: Ben Whitmore
Date: 9th July 2022
Thanks: @PMPC colleague(s) for "Current user" identitity and role functions
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[string]$URL = "https://download.microsoft.com/download/5/0/8/508918E1-3627-4383-B7D8-AA07B3490D21/ConfigMgrTools.msi",
[Parameter(Mandatory = $false)]
[string]$DownloadDir = $env:temp,
[Parameter(Mandatory = $false)]
[string]$DownloadFileName = "ConfigMgrTools.msi",
[Parameter(Mandatory = $false)]
[string]$InstallDest = "C:\Program Files (x86)\ConfigMgr 2012 Toolkit R2\ClientTools\CMTrace.exe"
)
##Set Verbose Level##
$VerbosePreference = "Continue"
#$VerbosePreference = "SilentlyContinue"
Function Get-URLHashInfo {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$URLPath
)
#Initialize WebClient class and return file hash of URI passed to the function
$WebClient = [System.Net.WebClient]::new()
$URLHash = Get-FileHash -Algorithm MD5 -InputStream ($WebClient.OpenRead($URLPath))
return $URLHash
}
Function Get-FileHashInfo {
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$FilePath
)
#Return file hash of file passed to the function
$FileHash = Get-FileHash -Algorithm MD5 -Path $FilePath
return $FileHash
}
Function Test-ElevatedSession {
#Get the current user
$CurrentUser = [Security.Principal.WindowsIdentity]::GetCurrent()
$IsAdmin = (New-Object Security.Principal.WindowsPrincipal $CurrentUser).IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
$IsSystem = $CurrentUser.User -eq 'S-1-5-18'
Write-Verbose "Current User = $($CurrentUser.Name)"
Write-Verbose "Current user is an administrator? $IsAdmin"
Write-Verbose "Running as SYSTEM? $IsSystem"
If ($IsAdmin -or $IsSystem) {
Write-Verbose "Session elevated? $true"
$ElevatedSession = $true
}
return $ElevatedSession
}
Function Get-FileFromInternet {
[CmdletBinding()]
Param (
[Parameter(Mandatory = $true)]
[ValidateScript({ $_.StartsWith("https://") })]
[String]$URL,
[Parameter(Mandatory = $true)]
[String]$Destination
)
#Test the URL is valid
Try {
$URLRequest = Invoke-WebRequest -UseBasicParsing -URI $URL -ErrorAction SilentlyContinue
$StatusCode = $URLRequest.StatusCode
}
Catch {
Write-Verbose "It looks like the URL is invalid. Please try again"
$StatusCode = $_.Exception.Response.StatusCode.value__
}
#If the URL is valid, attempt to download the file
If ($StatusCode -eq 200) {
Try {
Invoke-WebRequest -UseBasicParsing -Uri $URL -OutFile $Destination -ErrorAction SilentlyContinue
If (Test-Path $Destination) {
Write-Verbose "File download Successfull. File saved to $Destination"
}
else {
Write-Verbose "The download was interrupted or an error occured moving the file to the destination you specified"
break
}
}
Catch {
Write-Verbose "Error downloading file: $URL"
$_
break
}
}
else {
Write-Verbose "URL Does not exists or the website is down. Status Code: $($StatusCode)"
break
}
}
#Continue if the user running the script is a local administrator or SYSTEM
If (!(Test-ElevatedSession)) {
Write-Verbose "The script has not been run by an administrator or the SYSTEM account. Please re-run this script with administrator credentials or in the SYSTEM context."
}
else {
#Check the CLient Tools are not already installed
If (-not(Test-Path -Path $InstallDest)) {
#Set Download destination full path
$FilePath = (Join-Path -Path $DownloadDir -ChildPath $DownloadFileName)
#Download the MSI
Get-FileFromInternet -URL $URL -Destination $FilePath
#Test if the download was successful
If (-not (Test-Path -Path $FilePath)) {
Write-Verbose "There was an error downloading the file to the file system. $($FilePath) does not exist."
break
}
else {
#Check the hash from Microsoft matches the hash of the file saved to disk
$URLHash = (Get-URLHashInfo -URLPath $URL).hash
$FileHash = (Get-FileHashInfo -FilePath $FilePath).hash
Write-Verbose "Checking Hash.."
#Warn if the hash is different
If (($URLHash -ne $FileHash) -or ([string]::IsNullOrWhitespace($URLHash)) -or ([string]::IsNullOrWhitespace($FileHash))) {
Write-Verbose "URL Hash = $($URLHash)"
Write-Verbose "File Hash = $($FileHash)"
Write-Verbose "There was an error checking the hash value of the downloaded file. The file hash for ""$($FilePath)"" does not match the hash at ""$($URL)"". Aborting installation"
break
}
else {
Write-Verbose "Hash match confirmed. Continue installation.."
Try {
#Attempt to install the MSI
$MSIArgs = @(
"/i"
$FilePath
"ADDLOCAL=ClientTools"
"/qn"
)
Start-Process "$env:SystemRoot\System32\msiexec.exe" -args $MSIArgs -Wait -NoNewWindow
#Check the installation was successful
If (Test-Path -Path $InstallDest) {
Write-Verbose "CMTrace installed succesfully at $($InstallDest) "
}
}
Catch {
Write-Verbose "There was an error installing the CMTrace"
$_
}
}
}
}
else {
Write-Verbose "CMTrace is already installed at $($InstallDest). Installation will not continue."
}
}