Setup/Windows/ProxyAgent.wsf (902 lines of code) (raw):

<package> <?component error="true" debug="true" ?> <reference object="WbemScripting.SWbemLocator" /> <comment> Configures the Proxy Agent Service. </comment> <component id="ProxyAgent"> <registration progid="WaGuest.ProxyAgent" description="" version="1.0.0.0" clsid="{1ADC86E5-B1B6-4286-BC88-B1F6965D5E20}"/> <public> <property name="Script" /> <method name="Initialize"> <param name="proxyAgentPackageName" /> </method> <method name="ConfigureProxyAgent" /> <method name="UninstallProxyAgent" /> <method name="ConfigureProxyAgentOnly" /> <method name="UninstallProxyAgentOnly" /> <method name="PostInstallation" /> </public> <object id="WshShell" progid="WScript.Shell" /> <object id="FsObject" progid="Scripting.FileSystemObject" /> <script language="VBScript" src="Utility.vbs" /> <script language="VBScript"> Const ERROR_PROXYAGENT_PACKAGE_NOT_FOUND = 1 Const ERROR_AZURE_KEY_NOT_CONFIGURED = 2 Const ERROR_VM_TYPE_NOT_CONFIGURED = 3 Const ERROR_PROXYAGENT_KEY_NOT_CONFIGURED = 4 Const ERROR_PROXYAGENT_INCARNATION_NOT_CONFIGURED = 5 Const ERROR_PROXYAGENT_PACKAGE_NAME_NOTFOUND = 6 Const ERROR_PROXYAGENT_OS_NOT_SUPPORTED = 7 Const EBPF_FOR_WINDOWS_SOURCE_PATH = "ebpf-for-windows" Dim g_Trace Dim oTraceEvent Dim oProxyAgentPackageName Dim oProxyAgentBinaryLocation Dim oServiceAlreadyInstalled Dim oOldProxyAgentBinLocation Sub Initialize(proxyAgentPackageName) Set g_Trace = GetScriptObject(Me.Script, "Tracing.wsf", "TraceSource") g_Trace.Name = "ProxyAgent" if proxyAgentPackageName <> "." then oProxyAgentPackageName = proxyAgentPackageName else oProxyAgentPackageName = "" end if End Sub ' This function configures the Proxy Agent on the machine and returns true if the machine should be restarted after provisioning ' to complete this configuration. If no restart is required, this function returns false. Function ConfigureProxyAgent On Error Resume Next ConfigureProxyAgent = False oProxyAgentBinaryLocation = "" oServiceAlreadyInstalled = False oOldProxyAgentBinLocation = "" ' Stop GuestProxyAgent service before uninstall ebpf drivers because it has dependences oServiceAlreadyInstalled = CheckServiceInstalled("GuestProxyAgent") If oServiceAlreadyInstalled = True Then oOldProxyAgentBinLocation = GetServiceInstallLocation("GuestProxyAgent") ' Stop any running or already configured Proxy agent services. This will happen ' when captured roles are provisioned. If service is not running or not installed then ' its a no-op call StopServiceWait("GuestProxyAgent", "GuestProxyAgent.exe") If TraceError(g_Trace, "Stopping GuestProxyAgent service failed.") <> 0 Then Set oTraceEvent = g_Trace.CreateEvent("ERROR") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopGuestProxyAgentService")) .setAttribute "StopServiceErrorCode", errReturnCode End With g_Trace.TraceEvent oTraceEvent End If End If call UnzipProxyAgentPackage If TraceError(g_Trace, "Unzipping the Proxy Agent Package to " & oProxyAgentBinaryLocation & " failed.") <> 0 Then Exit Function End If ' Uninstall/InstallEbpf Dim scriptPath, ebpfSourcePath scriptPath = FsObject.GetParentFolderName(Me.Script.ScriptFullName) ebpfSourcePath : ebpfSourcePath = FsObject.BuildPath(scriptPath, EBPF_FOR_WINDOWS_SOURCE_PATH) call CleanInstallEbpf(ebpfSourcePath) If TraceError(g_Trace, "Installing eBPF failed.") <> 0 Then Exit Function End If ' Install GuestProxyAgent service call ConfigureGuestProxyAgentService If TraceError(g_Trace, "Installing the GuestProxyAgent service failed.") <> 0 Then UninstallEbpf(True) Exit Function End If call StartGuestProxyAgentService If TraceError(g_Trace, "Starting the GuestProxyAgent service failed") <> 0 Then Exit Function End If ConfigureProxyAgent = True If oServiceAlreadyInstalled = True and oOldProxyAgentBinLocation <> "" Then 'Remove Old folder - best effort Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("DeleteOldProxyAgentPackagesFolder")) .setAttribute "OldFolder", oOldProxyAgentBinLocation End With g_Trace.TraceEvent oTraceEvent call DeleteFolder(oOldProxyAgentBinLocation) TraceError g_Trace, "Deleting old packages folder '" & oOldProxyAgentBinLocation & "' failed." End If End Function Function ConfigureProxyAgentOnly On Error Resume Next ConfigureProxyAgentOnly = False oProxyAgentBinaryLocation = "" oServiceAlreadyInstalled = False oOldProxyAgentBinLocation = "" ' Stop GuestProxyAgent service before uninstall ebpf drivers because it has dependences oServiceAlreadyInstalled = CheckServiceInstalled("GuestProxyAgent") If oServiceAlreadyInstalled = True Then oOldProxyAgentBinLocation = GetServiceInstallLocation("GuestProxyAgent") ' Stop any running or already configured Proxy agent services. This will happen ' when captured roles are provisioned. If service is not running or not installed then ' its a no-op call StopServiceWait("GuestProxyAgent", "GuestProxyAgent.exe") If TraceError(g_Trace, "Stopping GuestProxyAgent service failed.") <> 0 Then Set oTraceEvent = g_Trace.CreateEvent("ERROR") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopGuestProxyAgentService")) .setAttribute "StopServiceErrorCode", errReturnCode End With g_Trace.TraceEvent oTraceEvent End If End If call UnzipProxyAgentPackage If TraceError(g_Trace, "Unzipping the Proxy Agent Package to " & oProxyAgentBinaryLocation & " failed.") <> 0 Then Exit Function End If ' Install GuestProxyAgent service call ConfigureGuestProxyAgentService If TraceError(g_Trace, "Installing the GuestProxyAgent service failed.") <> 0 Then UninstallEbpf(True) Exit Function End If call StartGuestProxyAgentService If TraceError(g_Trace, "Starting the GuestProxyAgent service failed") <> 0 Then Exit Function End If ConfigureProxyAgentOnly = True If oServiceAlreadyInstalled = True and oOldProxyAgentBinLocation <> "" Then 'Remove Old folder - best effort Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("DeleteOldProxyAgentPackagesFolder")) .setAttribute "OldFolder", oOldProxyAgentBinLocation End With g_Trace.TraceEvent oTraceEvent call DeleteFolder(oOldProxyAgentBinLocation) TraceError g_Trace, "Deleting old packages folder '" & oOldProxyAgentBinLocation & "' failed." End If End Function Function PostInstallation On Error Resume Next PostInstallation = True ' Create the tracing tasks if CreateEbpfTracingTasks() = False Then PostInstallation = False End If End Function 'This function Uninstalls the ProxyAgent - Pass "ServiceOnly" if folders are to be preserved Sub UninstallProxyAgent(uninstallMode) On Error Resume Next call UninstallProxyAgentOnly(uninstallMode) ' UninstallEbpf call UninstallEbpf(True) End Sub Sub UninstallProxyAgentOnly(uninstallMode) On Error Resume Next call UnregisterService("GuestProxyAgent", "GuestProxyAgent.exe") TraceError g_Trace, "Unregistering GuestProxyAgent service failed." If uninstallMode <> "ServiceOnly" Then call DeleteProxyAgentFolder TraceError g_Trace, "Deleting proxy agent folder failed." End If End Sub ' This function Enables the service if disabled and changes its start mode as requested. Sub EnableService(serviceName, startMode) Const MAX_ITER = 5 Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableService")) .setAttribute "ServiceName", serviceName End With g_Trace.TraceEvent oTraceEvent Set objWMIService = GetObject("winmgmts:\\.\root\cimv2") Set colService = objWMIService.ExecQuery( _ "Select * from Win32_Service Where Name = '" + serviceName + "'") For Each svc In colService If svc.StartMode = "Disabled" Then Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableService")) .setAttribute "EnablingDisabledService", serviceName End With g_Trace.TraceEvent oTraceEvent svc.ChangeStartMode(startMode) Else Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableService")) .setAttribute "AlreadyEnabledService", serviceName End With g_Trace.TraceEvent oTraceEvent End If Next ' This loop waits for the service to be enabled iter = 0 Do Set colService = objWMIService.ExecQuery( _ "Select * from Win32_Service Where Name = '" + serviceName + "'") done = True For Each svc In colService If svc.StartMode = "Disabled" Then done = False Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableService")) .setAttribute "WaitEnableServiceName", serviceName End With g_Trace.TraceEvent oTraceEvent ' Wait 2 secs before checking again Me.Script.Sleep 2000 Exit For Else Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableService")) .setAttribute "EnabledService", serviceName End With g_Trace.TraceEvent oTraceEvent End If Next iter = iter + 1 If iter > MAX_ITER Then Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableService")) .setAttribute "TimedOutEnableServiceName", serviceName End With g_Trace.TraceEvent oTraceEvent Exit Do End If Loop Until done End Sub Sub StopProcessWait(processName) Const MAX_ITER = 15 Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopProcessWait")) .setAttribute "ProcessName", processName End With g_Trace.TraceEvent oTraceEvent Set objWMI = GetObject("winmgmts:\\.\root\cimv2") iter = 0 Do Set colProcesses = objWMI.ExecQuery( _ "Select * from Win32_Process Where Name = '" + processName + "'") done = True If colProcesses.count <> 0 Then done = False Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopProcessWait")) .setAttribute "WaitForStopProcess", processName End With g_Trace.TraceEvent oTraceEvent ' Wait 2 secs before checking ProxyAgent Me.Script.Sleep 2000 Else Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopProcessWait")) .setAttribute "StoppedProcess", processName End With g_Trace.TraceEvent oTraceEvent End If iter = iter + 1 If iter > MAX_ITER Then Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopProcessWait")) .setAttribute "TimedOutStopProcess", processName End With g_Trace.TraceEvent oTraceEvent ' TimedOutWaiting - Kill processes For Each colProc in colProcesses errReturnCode = colProc.Terminate() Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopProcessWait")) .setAttribute "KilledProcess", colProc.ExecutablePath .setAttribute "returnedCode", errReturnCode End With g_Trace.TraceEvent oTraceEvent Next ' Wait some time to let the process get killed Me.Script.Sleep 2000 Exit Do End If Loop Until done End Sub ' This function checks if the service is installed. Function CheckServiceInstalled(serviceName) On Error Resume Next CheckServiceInstalled = False Dim objWMIService, colServices, serviceQuery, eventType serviceQuery = "Select * from Win32_Service where Name='" + serviceName + "'" Set objWMIService = GetObject("winmgmts:\\.\root\cimv2") Set colServices = objWMIService.ExecQuery(serviceQuery) For Each objService in colServices CheckServiceInstalled = True Next Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("CheckServiceInstalled")) .setAttribute "ServiceInstalled", CheckServiceInstalled End With g_Trace.TraceEvent oTraceEvent End Function ' This function Stops and wait for the service to stop. If the service is stopped or not there then its a no-op Sub StopServiceWait(serviceName, processName) Const MAX_ITER = 5 Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopServiceWait")) .setAttribute "ServiceName", serviceName End With g_Trace.TraceEvent oTraceEvent Set objWMIService = GetObject("winmgmts:\\.\root\cimv2") Set colService = objWMIService.ExecQuery( _ "Select * from Win32_Service Where Name = '" + serviceName + "'") For Each svc In colService svc.StopService Next ' Wait for its process to exit call StopProcessWait(processName) TraceError g_Trace, "Stopping process: " + processName + " failed." iter = 0 Do Set colService = objWMIService.ExecQuery( _ "Select * from Win32_Service Where Name = '" + serviceName + "'") done = True For Each svc In colService If svc.State <> "Stopped" Then done = False Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopServiceWait")) .setAttribute "WaitStopServiceName", serviceName End With g_Trace.TraceEvent oTraceEvent ' Wait 2 secs before checking again Me.Script.Sleep 2000 Exit For Else Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopServiceWait")) .setAttribute "StoppedService", serviceName End With g_Trace.TraceEvent oTraceEvent End If Next iter = iter + 1 If iter > MAX_ITER Then Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopServiceWait")) .setAttribute "TimedOutStopServiceName", serviceName End With g_Trace.TraceEvent oTraceEvent Exit Do End If Loop Until done End Sub ' This function unregisters a service. Sub UnregisterService(serviceName, processName) On Error Resume Next Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnregisterService")) .setAttribute "ServiceName", serviceName End With g_Trace.TraceEvent oTraceEvent Dim objWMIService, colServices, serviceQuery, eventType serviceQuery = "Select * from Win32_Service where Name='" + serviceName + "'" Set objWMIService = GetObject("winmgmts:\\.\root\cimv2") Set colServices = objWMIService.ExecQuery(serviceQuery) For Each objService in colServices errReturnCode = objService.StopService() If errReturnCode = 0 Or errReturnCode = 5 Or errorReturnCode = 10 Then ' Success Or Service Cannot Accept Control Or Service Already Stopped eventType = "INFO" Else eventType = "ERROR" End If Set oTraceEvent = g_Trace.CreateEvent(eventType) With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnregisterService")) .setAttribute "StopService", errReturnCode End With g_Trace.TraceEvent oTraceEvent ' Wait for its process to exit call StopProcessWait(processName) TraceError g_Trace, "Stopping process: " + processName + " failed." errReturnCode = objService.Delete() If errReturnCode = 0 Then eventType = "INFO" Else eventType = "ERROR" End If Set oTraceEvent = g_Trace.CreateEvent(eventType) With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnregisterService")) .setAttribute "DeleteService", errReturnCode End With g_Trace.TraceEvent oTraceEvent If errReturnCode <> 0 Then Exit Sub End If Next Set oTraceEvent = g_Trace.CreateEvent("INFO") oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnregisterService")) g_Trace.TraceEvent oTraceEvent End Sub ' This function deletes all the ProxyAgent specific folders on the filesystem. Sub DeleteProxyAgentFolder On Error Resume Next Dim proxyAgentPath proxyAgentPath = FsObject.BuildPath(WshShell.ExpandEnvironmentStrings("%SYSTEMDRIVE%"), "\WindowsAzure\ProxyAgent") call DeleteFolder(proxyAgentPath) End Sub ' This function deletes the folder specified in the path parameter. Sub DeleteFolder(path) On Error Resume Next FsObject.DeleteFolder path, True If Err.number <> 0 And Err.number <> 76 Then ' 76 - Path not found is not an issue when deleting Set oTraceEvent = g_Trace.CreateEvent("WARNING") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("DeleteFolder")) .setAttribute "Path", proxyAgentPath .setAttribute "Error", Err.number .setAttribute "Description", Err.Description End With g_Trace.TraceEvent oTraceEvent Else Err.number = 0 End If End Sub ' This function unzips the ProxyAgent package into %SYSTEMDRIVE%\WindowsAzure\ProxyAgent folder. Sub UnzipProxyAgentPackage On Error Resume Next Dim objProxyAgentZipLocation Dim extractToPath, zipPath, scriptDir Dim appendDirName Const FOF_SILENT = &H4& Const FOF_NOCONFIRMATION = &H10& Const FOF_NOERRORUI = &H400& scriptDir = FsObject.GetParentFolderName(Me.Script.ScriptFullName) zipPath = FsObject.BuildPath(scriptDir, "ProxyAgent\") zipPath = FsObject.BuildPath(zipPath, oProxyAgentPackageName) appendDirName = "" extractToPath = FsObject.BuildPath(WshShell.ExpandEnvironmentStrings("%SYSTEMDRIVE%"), "\WindowsAzure\") 'If the WindowsAzure folder does not exist create it. If Not FsObject.FolderExists(extractToPath) Then FsObject.CreateFolder(extractToPath) If Err.number <> 0 Then Set oTraceEvent = g_Trace.CreateEvent("ERROR") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnzipProxyAgentPackage")) .setAttribute "WindowsAzureCreateFolderFailed", Err.number .setAttribute "Description", Err.Description End With g_Trace.TraceEvent oTraceEvent Exit Sub End If Else Set oTraceEvent = g_Trace.CreateEvent("WARN") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnzipProxyAgentPackage")) .setAttribute "WindowsAzureFolderExists", True End With g_Trace.TraceEvent oTraceEvent End If extractToPath = FsObject.BuildPath(extractToPath, "ProxyAgent\") 'If the ProxyAgent folder does not exist create it. If Not FsObject.FolderExists(extractToPath) Then FsObject.CreateFolder(extractToPath) If Err.number <> 0 Then Set oTraceEvent = g_Trace.CreateEvent("ERROR") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnzipProxyAgentPackage")) .setAttribute "WindowsAzureProxyAgentCreateFolderFailed", Err.number .setAttribute "Description", Err.Description End With g_Trace.TraceEvent oTraceEvent Exit Sub End If Else Set oTraceEvent = g_Trace.CreateEvent("WARN") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnzipProxyAgentPackage")) .setAttribute "WindowsAzureProxyAgentFolderExists", True End With g_Trace.TraceEvent oTraceEvent End If If oServiceAlreadyInstalled = True Then ' If service already there then create a new unique folder with date stamp Dim myTime myTime = Now appendDirName = "_" & Year(myTime) & Month(myTime) & Day(myTime) & "_" & Hour(myTime) & Minute(myTime) & Second(myTime) End If extractToPath = FsObject.BuildPath(extractToPath, "Package" & appendDirName & "\") oProxyAgentBinaryLocation = extractToPath 'If the Packages folder does not exist create it. If Not FsObject.FolderExists(extractToPath) Then FsObject.CreateFolder(extractToPath) If Err.number <> 0 Then Set oTraceEvent = g_Trace.CreateEvent("ERROR") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnzipProxyAgentPackage")) .setAttribute "WindowsAzurePackagesCreateFolderFailed", Err.number .setAttribute "Description", Err.Description End With g_Trace.TraceEvent oTraceEvent Exit Sub End If Else Set oTraceEvent = g_Trace.CreateEvent("ERROR") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnzipProxyAgentPackage")) .setAttribute "WindowsAzurePackagesFolderExists", True End With g_Trace.TraceEvent oTraceEvent End If 'Extract the contents of the zip file. Set objShell = CreateObject("Shell.Application") Set FilesInZip=objShell.NameSpace(zipPath).items cFlags = FOF_SILENT + FOF_NOCONFIRMATION + FOF_NOERRORUI objShell.NameSpace(extractToPath).CopyHere FilesInZip, cFlags Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnzipProxyAgentPackage")) .setAttribute "ZipLocation", zipPath .setAttribute "ExtractionLocation", extractToPath End With g_Trace.TraceEvent oTraceEvent End Sub ' This function registers the proxy agent service. Sub ConfigureGuestProxyAgentService On Error Resume Next Dim objWMIService, objService, servicePath, errReturnCode Const OWN_PROCESS = 16 Const NOT_INTERACTIVE = False Const NORMAL_ERROR_CONTROL = 1 Dim ebpfServices ebpfServices = Array ("EbpfCore", "NetEbpfExt") Set objWMIService = GetObject("winmgmts:\\.\root\cimv2") Set objService = objWMIService.Get("Win32_BaseService") servicePath = FsObject.BuildPath(oProxyAgentBinaryLocation, "\GuestProxyAgent.exe") If oServiceAlreadyInstalled = False then ' Create service with serviceDependencies on ebpfServices errReturnCode = objService.Create("GuestProxyAgent", "Microsoft Azure Guest Proxy Agent", servicePath, OWN_PROCESS, NORMAL_ERROR_CONTROL, "Automatic", _ NOT_INTERACTIVE, NULL, NULL, NULL, NULL, ebpfServices) Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ConfigureGuestProxyAgentService")) .setAttribute "CreateService", errReturnCode End With g_Trace.TraceEvent oTraceEvent Else ' Change service settings with new path call SetServicePathInRegistry("GuestProxyAgent", servicePath) If TraceError(g_Trace, "Setting the new GuestProxyAgent service path in registry failed.") <> 0 Then Set oTraceEvent = g_Trace.CreateEvent("ERROR") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ConfigureGuestProxyAgentService")) .setAttribute "Failed to update GuestProxyAgent path", Err.number End With g_Trace.TraceEvent oTraceEvent Exit Sub End If ' Enables service if not enabled. This is needed for the service disabled during sysprep process. call EnableService("GuestProxyAgent", "Automatic") If TraceError(g_Trace, "Enabling GuestProxyAgent service failed.") <> 0 Then Set oTraceEvent = g_Trace.CreateEvent("ERROR") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ConfigureGuestProxyAgentService")) .setAttribute "EnableServiceErrorCode", errReturnCode End With g_Trace.TraceEvent oTraceEvent End If Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ConfigureGuestProxyAgentService")) .setAttribute "ChangeService", errReturnCode End With g_Trace.TraceEvent oTraceEvent End If End Sub ' Start the installer service Sub StartGuestProxyAgentService On Error Resume Next Dim objWMIService, colServices Set objWMIService = GetObject("winmgmts:\\.\root\cimv2") Set colServices = objWMIService.ExecQuery _ ("Select * from Win32_Service where Name='GuestProxyAgent'") For each objService in colServices errReturnCode = objService.StartService() Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StartGuestProxyAgentService")) .setAttribute "StartService", errReturnCode End With g_Trace.TraceEvent oTraceEvent If errReturnCode <> 0 Then Exit Sub End If Next Set oTraceEvent = g_Trace.CreateEvent("INFO") oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StartGuestProxyAgentService")) g_Trace.TraceEvent oTraceEvent End Sub ' Set the service registry path Sub SetServicePathInRegistry (serviceName, servicePath) On Error Resume Next Dim strKeyPath const HKEY_LOCAL_MACHINE = &H80000002 const strComputer = "." strKeyPath = "SYSTEM\CurrentControlSet\Services\" & serviceName Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv") objReg.CreateKey HKEY_LOCAL_MACHINE, strKeyPath objReg.SetStringValue HKEY_LOCAL_MACHINE, strKeyPath, "ImagePath", servicePath Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("SetGuestProxyAgentServicePathInRegistry")) .setAttribute "ServiceName", serviceName .setAttribute "ServiceImagePath", servicePath End With g_Trace.TraceEvent oTraceEvent End Sub ' Get service install location the incarnation in registry for ProxyAgent to use at runtime Function GetServiceInstallLocation(serviceName) On Error Resume Next Dim strKeyPath, servicePath const HKEY_LOCAL_MACHINE = &H80000002 const strComputer = "." strKeyPath = "SYSTEM\CurrentControlSet\Services\" & serviceName Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv") objReg.GetStringValue HKEY_LOCAL_MACHINE, strKeyPath, "ImagePath", servicePath Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("GetServiceInstallLocation")) .setAttribute "ServiceName", serviceName .setAttribute "ServiceImagePath", servicePath End With g_Trace.TraceEvent oTraceEvent GetServiceInstallLocation = FsObject.GetParentFolderName(servicePath) End Function '------------------------------------------------------------------- '------------- EBPF Install/Uninstall Functions -------------------- '------------------------------------------------------------------- ' String constants Const EBPF_EBPFCORE_DRIVER_NAME = "eBPFCore" Const EBPF_EXTENSION_DRIVER_NAME = "NetEbpfExt" Const EBPF_TRACING_STARTUP_TASK_NAME = "eBpfTracingStartupTask" Const EBPF_TRACING_STARTUP_TASK_FILENAME = "ebpf_tracing_startup_task.xml" Const EBPF_TRACING_PERIODIC_TASK_NAME = "eBpfTracingPeriodicTask" Const EBPF_TRACING_PERIODIC_TASK_FILENAME = "ebpf_tracing_periodic_task.xml" Const EBPF_TRACING_TASK_CMD = "ebpf_tracing.cmd" ' Global variables Dim WmiService : Set WmiService = GetObject("winmgmts:\\.\root\cimv2") Dim g_tracingPath: g_tracingPath = FsObject.BuildPath(WshShell.ExpandEnvironmentStrings("%SystemRoot%"), "\Logs\eBPF") Dim g_installPath: g_installPath = FsObject.BuildPath(WshShell.ExpandEnvironmentStrings("%ProgramFiles%"), "\ebpf-for-windows") ' Adds a new path to the System path, unless the path is already present in the system path. Function AddSystemPath(pathToAdd) On Error Resume Next AddSystemPath = True Dim sysENV : Set sysENV = WshShell.Environment("System") systemPath = sysENV("PATH") If InStr(systemPath, pathToAdd) = 0 Then sysENV("PATH") = systemPath + ";" + pathToAdd End If Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("AddSystemPath")) .setAttribute "pathToAdd", pathToAdd End With g_Trace.TraceEvent oTraceEvent End Function ' Removes the given path from the System path, unless the path isn't present. Function RemoveSystemPath(pathToRemove) On Error Resume Next RemoveSystemPath = True Dim sysENV : Set sysENV = WshShell.Environment("System") systemPath = sysENV("PATH") If InStr(systemPath, pathToRemove) <> 0 Then systemPath = Replace(systemPath, pathToRemove, "") systemPath = Replace(systemPath, ";;", ";") sysENV("PATH") = systemPath End If Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("RemoveSystemPath")) .setAttribute "pathToRemove", pathToRemove End With g_Trace.TraceEvent oTraceEvent End Function ' This function moves the files from the source folder to the destination folder Function CopyFilesToPath(sourcePath, destPath) On Error Resume Next CopyFilesToPath = True ' Create the destination folder if it doesn't exist If Not FsObject.FolderExists(destPath) Then call FsObject.CreateFolder(destPath) If TraceError(g_Trace, "Failed to create folder " + destPath) <> 0 Then CopyFilesToPath = False End If End If If CopyFilesToPath = True Then ' Copy the files to the destination folder FsObject.CopyFolder sourcePath, destPath, True If TraceError(g_Trace, "Failed to copy files from " + sourcePath + " to " + destPath) <> 0 Then CopyFilesToPath = False End If End If End Function ' Creates a scheduled task using the given task file returns the exitcode of schtasks Function CreateScheduledTask(taskName, taskFile) On Error Resume Next Dim oResults, oTraceEvent, taskCommand taskCommand = "%SystemRoot%\System32\schtasks.exe /create /tn " & taskName & " /xml """ & taskFile & """" Set oResults = ExecuteAndTraceWithResults(taskCommand, g_Trace) If oResults.ExitCode = 0 Then Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("CreateScheduledTask")) .setAttribute "task", CStr(taskName) End With g_Trace.TraceEvent oTraceEvent End If CreateScheduledTask = oResults.ExitCode End Function ' Delete a scheduled task returns the exitcode of schtasks Function DeleteScheduledTask(taskName) On Error Resume Next Dim oResults, oTraceEvent, taskCommand taskCommand = "%SystemRoot%\System32\schtasks.exe /delete /tn " & taskName & " /f" Set oResults = ExecuteAndTraceWithResults(taskCommand, g_Trace) If oResults.ExitCode = 0 Then Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("DeleteScheduledTask")) .setAttribute "task", CStr(taskName) End With g_Trace.TraceEvent oTraceEvent End If DeleteScheduledTask = oResults.ExitCode End Function ' This function creates tasks to start eBPF tracing at boot, and execute periodic rundowns Function CreateEbpfTracingTasks() On Error Resume Next CreateEbpfTracingTasks = true Dim taskFilePath ' Delete the tasks if they already exist call DeleteEbpfTracingTasks() ' Create the scheduled tasks taskFilePath = FsObject.BuildPath(g_installPath, EBPF_TRACING_STARTUP_TASK_FILENAME) if CreateScheduledTask(EBPF_TRACING_STARTUP_TASK_NAME, taskFilePath) <> 0 Then CreateEbpfTracingTasks = False Exit Function End If taskFilePath = FsObject.BuildPath(g_installPath, EBPF_TRACING_PERIODIC_TASK_FILENAME) if CreateScheduledTask(EBPF_TRACING_PERIODIC_TASK_NAME, taskFilePath) <> 0 Then call DeleteEbpfTracingTasks() CreateEbpfTracingTasks = False End If End Function ' This function deletes the tasks to start eBPF tracing at boot, and execute periodic rundowns, and deletes the g_tracingPath Function DeleteEbpfTracingTasks() On Error Resume Next Const THIS_FUNCTION_NAME = "DeleteEbpfTracingTasks" DeleteEbpfTracingTasks = True ' Execute the script to stop eBPF tracing Dim scriptPath : scriptPath = FsObject.BuildPath(g_installPath, EBPF_TRACING_TASK_CMD) If FsObject.FileExists(scriptPath) Then Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement(THIS_FUNCTION_NAME)) .setAttribute "StopEbpfTracing", scriptPath End With g_Trace.TraceEvent oTraceEvent If ExecuteAndTraceWithResults("""" + scriptPath + """ stop /trace_path """ + g_tracingPath + """", g_trace).ExitCode <> 0 Then DeleteEbpfTracingTasks = False End If Else Set oTraceEvent = g_Trace.CreateEvent("ERROR") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement(THIS_FUNCTION_NAME)) .setAttribute "EbpfTaskScriptNotFound", scriptPath End With g_Trace.TraceEvent oTraceEvent End If ' Delete the startup task. if it already exists if DeleteScheduledTask(EBPF_TRACING_STARTUP_TASK_NAME) <> 0 Then DeleteEbpfTracingTasks = False End If ' Delete the periodic task. if it already exists if DeleteScheduledTask(EBPF_TRACING_PERIODIC_TASK_NAME) <> 0 Then DeleteEbpfTracingTasks = False End If End Function ' This function checks if the given driver is already installed. Function CheckDriverInstalled(driverName) On Error Resume Next CheckDriverInstalled = False Dim colServices, serviceQuery serviceQuery = "Select * from Win32_BaseService where Name='" + driverName + "'" Set colServices = WmiService.ExecQuery(serviceQuery) For Each objService in colServices CheckDriverInstalled = True Exit For Next End Function ' This function installs the given kernel driver. Function InstallEbpfDriver(driverName) On Error Resume Next InstallEbpfDriver = True Dim driverFullPath: driverFullPath = FsObject.BuildPath(g_installPath, "\drivers\" + driverName + ".sys") Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("InstallEbpfDriver")) .setAttribute "driverFullPath", driverFullPath End With g_Trace.TraceEvent oTraceEvent Dim oResults: Set oResults = ExecuteAndTraceWithResults("sc.exe create " + driverName + " type=kernel start=auto binpath=""" + driverFullPath + """", g_trace) if oResults.ExitCode <> 0 Then InstallEbpfDriver = False End If End Function ' This function stops then uninstalls the given kernel driver. Function UninstallEbpfDriver(driverName) On Error Resume Next Const THIS_FUNCTION_NAME = "UninstallEbpfDriver" Dim colServices, serviceQuery, errReturnCode UninstallEbpfDriver = True Dim driverFullPath: driverFullPath = FsObject.BuildPath(g_installPath, "\drivers\" + driverName + ".sys") serviceQuery = "Select * from Win32_BaseService where Name='" + driverName + "'" Set colServices = WmiService.ExecQuery(serviceQuery) For Each objService in colServices Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement(THIS_FUNCTION_NAME)) .setAttribute "driverFullPath", driverFullPath End With g_Trace.TraceEvent oTraceEvent errReturnCode = objService.StopService() If errReturnCode <> 0 Then UninstallEbpfDriver = False Set oTraceEvent = g_Trace.CreateEvent("ERROR") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement(THIS_FUNCTION_NAME)) .setAttribute "StopDriver", "False" .setAttribute "driverFullPath", driverFullPath End With g_Trace.TraceEvent oTraceEvent End If errReturnCode = objService.Delete() If errReturnCode <> 0 Then UninstallEbpfDriver = False Set oTraceEvent = g_Trace.CreateEvent("ERROR") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement(THIS_FUNCTION_NAME)) .setAttribute "deleteDriver", "False" .setAttribute "driverFullPath", driverFullPath End With g_Trace.TraceEvent oTraceEvent End If Next End Function ' This function uninstalls eBPF for Windows on the machine and returns true successful, false otherwise Function UninstallEbpf(shouldDeleteEbpfTracingTasks) On Error Resume Next UninstallEbpf = True Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UninstallEbpf")) .setAttribute "g_installPath", g_installPath .setAttribute "installationPathPresent", FsObject.FolderExists(g_installPath) End With g_Trace.TraceEvent oTraceEvent If UninstallEbpfDriver(EBPF_EBPFCORE_DRIVER_NAME) = False Then UninstallEbpf = False End If If UninstallEbpfDriver(EBPF_EXTENSION_DRIVER_NAME) = False Then UninstallEbpf = False End If If shouldDeleteEbpfTracingTasks = True Then If DeleteEbpfTracingTasks() = False Then UninstallEbpf = False End If End If if RemoveSystemPath(g_installPath) = False Then UninstallEbpf = False End If call DeleteFolder(g_installPath) End Function ' This function installs eBPF for Windows on the machine and returns true successful, false otherwise Function CleanInstallEbpf(sourcePath) On Error Resume Next CleanInstallEbpf = True Set oTraceEvent = g_Trace.CreateEvent("INFO") With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("CleanInstallEbpf")) .setAttribute "sourcePath", sourcePath .setAttribute "g_installPath", g_installPath .setAttribute "installationPathPresent", FsObject.FolderExists(g_installPath) End With g_Trace.TraceEvent oTraceEvent CleanInstallEbpf = UninstallEbpf(False) ' Move the files to the install path if Not CopyFilesToPath(sourcePath, g_installPath) Then CleanInstallEbpf = False Exit Function End If ' Install the drivers and add the install path to the system path If InstallEbpfDriver(EBPF_EBPFCORE_DRIVER_NAME) = False Then CleanInstallEbpf = False Exit Function End If If InstallEbpfDriver(EBPF_EXTENSION_DRIVER_NAME) = False Then CleanInstallEbpf = False call UninstallEbpfDriver(EBPF_EBPFCORE_DRIVER_NAME) Exit Function End If if AddSystemPath(g_installPath) = False Then CleanInstallEbpf = False End If End Function </script> </component> </package>