File: C:/Windows/OEM/GuestAgent.wsf
<package>
<?component error="true" debug="true" ?>
<reference object="WbemScripting.SWbemLocator" />
<comment>
Configures the Guest Agent Service.
</comment>
<component id="GuestAgent">
<registration
progid="WaGuest.GuestAgent"
description=""
version="1.0.0.0"
clsid="{cfd6b1a2-1f62-4a64-ad9d-6ceb9e183aab}"/>
<public>
<property name="WScript" />
<method name="Initialize">
<param name="gaPackageName" />
</method>
<method name="ConfigureGuestAgent">
<param name="kvpPrefix" />
<param name="offlineMode" />
</method>
<method name="ConfigureGuestAgentOfflined">
<param name="kvpPrefix" />
<param name="offlineMode" />
</method>
<method name="UninstallGuestAgent">
<param name="uninstallMode" />
<param name="kvpPrefix" />
</method>
</public>
<object id="WshShell" progid="WScript.Shell" />
<script language="VBScript" src="Utility.vbs" />
<script language="VBScript">
Const ERROR_GAPACKAGENOTFOUND = 1
Const ERROR_AZUREKEYNOTCONFIGURED = 2
Const ERROR_VMTYPENOTCONFIGURED= 3
Const ERROR_GUESTAGENTKEYNOTCONFIGURED = 4
Const ERROR_GAINCARNATIONNOTCONFIGURED = 5
Const ERROR_GAPACKAGENAMENOTFOUND = 6
Const ERROR_SERVICEINSTALLEDNOTVERIFIED = 7
Const ERROR_ENABLESERVICEFAILED = 8
Const ERROR_STARTSERVICE = 9
Dim g_Trace
Dim oTraceEvent
Dim oGAPackageName
Dim oGuestAgentBinaryLocation
Dim oExtractedAgentLocation
Dim oServiceAlreadyInstalled
Dim oOldGuestAgentBinLocation
Sub Initialize(gaPackageName)
Set g_Trace = GetScriptObject(Me.WScript, "Tracing.wsf", "TraceSource")
g_Trace.Name = "GuestAgent"
if gaPackageName <> "." then
oGAPackageName = gaPackageName
else
oGAPackageName = ""
end if
End Sub
' This function configures the Guest 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.
' kvpPrefix: The KVP prefix to use when logging new procedures
' offlineMode: Boolean indicating if the guest agent is being configured
' as disabled (offlineMode=true) or enabled (offlineMode=false)
Function ConfigureGuestAgent(kvpPrefix, offlineMode)
On Error Resume Next
Dim dotNetExists
dotNetExists = False
ConfigureGuestAgent = False
oGuestAgentBinaryLocation = ""
oExtractedAgentLocation = ""
oServiceAlreadyInstalled = False
oOldGuestAgentBinLocation = ""
oWindowsAzureGuestAgentInstalled = False
oTelemetryServiceAlreadyInstalled = False
If InstrumentProcedure("VerifyOsRequirements", "", True, False, kvpPrefix & "0_VerifyOsRequirements", g_Trace) = True Then
oServiceAlreadyInstalled = InstrumentProcedure("CheckServiceInstalled", """RdAgent""", True, False, kvpPrefix & "1_CheckServiceInstalled", g_Trace)
If oServiceAlreadyInstalled = True Then
oOldGuestAgentBinLocation = InstrumentProcedure("GetServiceInstallLocation", """RdAgent""", True, False, kvpPrefix & "2_GetServiceInstallLocation", g_Trace)
End If
oWindowsAzureGuestAgentInstalled = InstrumentProcedure("CheckServiceInstalled", """WindowsAzureGuestAgent""", True, False, kvpPrefix & "3_CheckServiceInstalledForWindosAzureGuestAgent", g_Trace)
oTelemetryServiceAlreadyInstalled = InstrumentProcedure("CheckServiceInstalled", """WindowsAzureTelemetryService""", True, False, kvpPrefix & "4_CheckServiceInstalledAzureTelemetryService", g_Trace)
' Stop any running or already configured Guest agent services. This will happen
' when captured roles are provisioned. If service is not running or not installed then
' its a no-op
if oServiceAlreadyInstalled = True Then
Call InstrumentProcedure("StopServiceWait", """RdAgent"", ""WaAppAgent.exe""", False, False, kvpPrefix & "5_StopServiceWait-RdAgent", g_Trace)
If TraceError(g_Trace, "Stopping RdAgent service failed.") <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopRdAgentService"))
.setAttribute "StopServiceErrorCode", errReturnCode
End With
g_Trace.TraceEvent oTraceEvent
End If
End If
if oWindowsAzureGuestAgentInstalled = True Then
Call InstrumentProcedure("StopServiceWait", """WindowsAzureGuestAgent"", ""WindowsAzureGuestAgent.exe""", False, False, kvpPrefix & "6_StopServiceWait-WindowsAzureGuestAgent", g_Trace)
If TraceError(g_Trace, "Stopping WindowsAzureGuestAgent service failed.") <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopGuestAgentService"))
.setAttribute "StopServiceErrorCode", errReturnCode
End With
g_Trace.TraceEvent oTraceEvent
End If
End If
If oTelemetryServiceAlreadyInstalled = True Then
Call InstrumentProcedure("StopServiceWait", """WindowsAzureTelemetryService"", ""WindowsAzureTelemetryService.exe""", False, False, kvpPrefix & "7_StopServiceWait-WindowsAzureTelemetryService", g_Trace)
If TraceError(g_Trace, "Stopping WindowsAzureTelemetryService service failed.") <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopTelemetryService"))
.setAttribute "StopServiceErrorCode", errReturnCode
End With
g_Trace.TraceEvent oTraceEvent
End If
End If
Call InstrumentProcedure("StopEventTrace", "", False, False, kvpPrefix & "8_StopEventTrace", g_Trace)
TraceError g_Trace, "Stopping trace for guestagent logs failed."
Call InstrumentProcedure("DeleteEventTrace", "", False, False, kvpPrefix & "9_DeleteEventTrace", g_Trace)
TraceError g_Trace, "Deleting trace for guestagent logs failed."
Call InstrumentProcedure("UnzipGuestAgentPackage", "", False, False, kvpPrefix & "10_UnzipGuestAgentPackage", g_Trace)
If TraceError(g_Trace, "Unzipping the Guest Agent Package to " & oExtractedAgentLocation & " failed.") <> 0 Then
Exit Function
End If
' Inform ConfigureRdAgentSerivce whether to enable RdAgent service when creating the services
Call InstrumentProcedure("ConfigureRdAgentService", BoolToString(offlineMode), False, False, kvpPrefix & "11_ConfigureRdAgentService", g_Trace)
If TraceError(g_Trace, "Installing the RdAgent service failed.") <> 0 Then
Exit Function
End If
Call InstrumentProcedure("SetVmTypeInRegistry", "", False, False, kvpPrefix & "12_SetVmTypeInRegistry", g_Trace)
If TraceError(g_Trace, "Setting the VMType in registry failed.") <> 0 Then
Exit Function
End If
' VM is not being provisioned if we are in offline mode
' inform SetGAParamsInRegistry about our mode to prevent logging provision time
Call InstrumentProcedure("SetGAParamsInRegistry", BoolToString(offlineMode), False, False, kvpPrefix & "13_SetGAParamsInRegistry", g_Trace)
If TraceError(g_Trace, "Setting the GA Settings in registry failed.") <> 0 Then
Exit Function
End If
dotNetExists = InstrumentProcedure("ValidDotNetVersionExists", "", True, False, kvpPrefix & "14_ValidDotNetVersionExists", g_Trace)
If TraceError(g_Trace, "Checking for the DotNetVersion failed.") <> 0 Then
Exit Function
End If
If dotNetExists = True Then
' Nested condition: If we are in offlineMode, we don't want to enable the services
' But we also don't want to reboot strictly because of the guest agent requirements
If offlineMode = False Then
' Enables service if not enabled. This is needed for the service disabled during sysprep process.
Call InstrumentProcedure("EnableService", """RdAgent"", ""Automatic""", False, False, kvpPrefix & "15_EnableService-RdAgent", g_Trace)
If TraceError(g_Trace, "Enabling RdAgent service failed.") <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableRdAgentService"))
.setAttribute "EnableServiceErrorCode", errReturnCode
End With
g_Trace.TraceEvent oTraceEvent
End If
Call InstrumentProcedure("EnableService", """WindowsAzureGuestAgent"", ""Automatic""", False, False, kvpPrefix & "16_EnableService-WindowsAzureGuestAgent", g_Trace)
If TraceError(g_Trace, "Enabling WindowsAzureGuestAgent service failed.") <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableWindowsAzureGuestAgentService"))
.setAttribute "EnableServiceErrorCode", errReturnCode
End With
g_Trace.TraceEvent oTraceEvent
End If
Call InstrumentProcedure("EnableService", """WindowsAzureTelemetryService"", ""Automatic""", False, False, kvpPrefix & "17_EnableService-WindowsAzureTelemetryService", g_Trace)
If TraceError(g_Trace, "Enabling WindowsAzureTelemetryService service failed.") <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableWindowsAzureTelemetryServiceService"))
.setAttribute "EnableServiceErrorCode", errReturnCode
End With
g_Trace.TraceEvent oTraceEvent
End If
Call InstrumentProcedure("StartRdAgentService", "", False, False, kvpPrefix & "18_StartRdAgentService", g_Trace)
If TraceError(g_Trace, "Starting the RdAgent service failed") <> 0 Then
Exit Function
End If
End If
Else
ConfigureGuestAgent = True
End If
If oServiceAlreadyInstalled = True and oOldGuestAgentBinLocation <> "" Then
'Remove Old folder - best effort
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("DeleteOldPackagesFolder"))
.setAttribute "OldFolder", oOldGuestAgentBinLocation
End With
g_Trace.TraceEvent oTraceEvent
Call InstrumentProcedure("DeleteFolder", """" & oOldGuestAgentBinLocation & """", False, False, kvpPrefix & "19_DeleteFolder", g_Trace)
TraceError g_Trace, "Deleting old packages folder '" & oOldGuestAgentBinLocation & "' failed."
End If
Else
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ConfigureGuestAgent"))
.setAttribute "VerifyOsRequirements", CStr(False)
End With
g_Trace.TraceEvent oTraceEvent
End If
End Function
' This function configures the Guest Agent on the machine that has been offlined/preprovisioned
Function ConfigureGuestAgentOfflined(kvpPrefix, offlineMode)
On Error Resume Next
Dim dotNetExists
If offlineMode = True Then
' This scenario means that we are configuring the guest agent
' in a preprovision state (offlineMode) but the guest agent
' has already been configured (on the VHD itself)
' This is a no-op as we have to wait for reprovision before enabling the services
Exit Function
End If
ConfigureGuestAgentOfflined = False
oGuestAgentBinaryLocation = ""
oExtractedAgentLocation = ""
oServiceAlreadyInstalled = True
oOldGuestAgentBinLocation = ""
Call InstrumentProcedure("SetGAParamsInRegistryOfflined", "", False, False, kvpPrefix & "0_SetGAParamsInRegistryOfflined", g_Trace)
If TraceError(g_Trace, "Setting the GA Settings in registry failed.") <> 0 Then
Exit Function
End If
dotNetExists = InstrumentProcedure("ValidDotNetVersionExists", "", True, False, kvpPrefix & "1_ValidDotNetVersionExists", g_Trace)
If TraceError(g_Trace, "Checking for the DotNetVersion failed.") <> 0 Then
Exit Function
End If
' Enable RDAgent even when restart is required.
' This ensures that RdAgent launches on restart and installs .NET Framework if needed
' This is already done in non-offline mode when we create the service
Call InstrumentProcedure("EnableService", QuoteString("RdAgent") & ", " & QuoteString("Automatic"), False, False, kvpPrefix & "2_EnableServiceOfflined-RdAgent", g_Trace)
If TraceError(g_Trace, "Enabling RdAgent service failed.") <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableRdAgentServiceOfflined"))
.setAttribute "EnableServiceErrorCode", errReturnCode
End With
g_Trace.TraceEvent oTraceEvent
End If
If dotNetExists = True Then
' Enables service if not enabled. This is needed because we disabled the service when configuring in offline mode
Call InstrumentProcedure("EnableService", QuoteString("WindowsAzureGuestAgent") & ", " & QuoteString("Automatic"), False, False, kvpPrefix & "3_EnableServiceOfflined-WindowsAzureGuestAgent", g_Trace)
If TraceError(g_Trace, "Enabling WindowsAzureGuestAgent service failed.") <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableWindowsAzureGuestAgentServiceOfflined"))
.setAttribute "EnableServiceErrorCode", errReturnCode
End With
g_Trace.TraceEvent oTraceEvent
End If
Call InstrumentProcedure("EnableService", QuoteString("WindowsAzureTelemetryService") & ", " & QuoteString("Automatic"), False, False, kvpPrefix & "4_EnableServiceOfflined-WindowsAzureTelemetryService", g_Trace)
If TraceError(g_Trace, "Enabling WindowsAzureTelemetryService service failed.") <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableWindowsAzureTelemetryServiceServiceOfflined"))
.setAttribute "EnableServiceErrorCode", errReturnCode
End With
g_Trace.TraceEvent oTraceEvent
End If
Call InstrumentProcedure("StartRdAgentService", "", False, False, kvpPrefix & "5_StartRdAgentServiceOfflined", g_Trace)
If TraceError(g_Trace, "Starting the RdAgent service failed") <> 0 Then
Exit Function
End If
Else
ConfigureGuestAgentOfflined = True
End If
End Function
' This function returns True if a valid version of DotNet is present for the GA to run. If not it returns false
Function ValidDotNetVersionExists
On Error Resume Next
Const KeyPath = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\NET Framework Setup\NDP\v4\Full"
Const ValueName = "Install"
Dim dotNetVersionExists, dwValue, eventType
dotNetVersionExists = False
dwValue = GetRegistryValue(g_Trace, KeyPath, ValueName, "REG_DWORD", False)
If Not IsNull(dwValue) Then
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ValidDotNetVersionExists"))
.setAttribute "dwValueReturned", dwValue
End With
g_Trace.TraceEvent oTraceEvent
dotNetVersionExists = True
End If
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ValidDotNetVersionExists"))
.setAttribute "ValidDotNetVersionExists", CStr(dotNetVersionExists)
End With
g_Trace.TraceEvent oTraceEvent
ValidDotNetVersionExists = dotNetVersionExists
End Function
'This function Uninstalls the GuestAgent - Pass "ServiceOnly" if folders are to be preserved
Sub UninstallGuestAgent(uninstallMode, kvpPrefix)
On Error Resume Next
Call InstrumentProcedure("UnregisterService", """RdAgent"", ""WaAppAgent.exe""", False, False, kvpPrefix & "0_UnregisterService-RdAgent", g_Trace)
TraceError g_Trace, "Unregistering RdAgent service failed."
Call InstrumentProcedure("UnregisterService", """WindowsAzureGuestAgent"", ""WindowsAzureGuestAgent.exe""", False, False, kvpPrefix & "1_UnregisterService-WindowsAzureGuestAgent", g_Trace)
TraceError g_Trace, "Unregistering WindowsAzureGuestAgent service failed."
Call InstrumentProcedure("UnregisterService", """WindowsAzureTelemetryService"", ""WindowsAzureTelemetryService.exe""", False, False, kvpPrefix & "2_UnregisterService-WindowsAzureTelemetryService", g_Trace)
TraceError g_Trace, "Unregistering WindowsAzureTelemetryService service failed."
Call InstrumentProcedure("StopEventTrace", "", False, False, kvpPrefix & "3_StopEventTrace", g_Trace)
TraceError g_Trace, "Stopping trace for guestagent logs failed."
Call InstrumentProcedure("DeleteEventTrace", "", False, False, kvpPrefix & "4_DeleteEventTrace", g_Trace)
TraceError g_Trace, "Deleting trace for guestagent logs failed."
If uninstallMode <> "ServiceOnly" Then
Call InstrumentProcedure("DeleteAzureFolders", "", False, False, kvpPrefix & "5_DeleteAzureFolders", g_Trace)
TraceError g_Trace, "Deleting azure folders failed."
Call InstrumentProcedure("DeleteAzureRegistryKeys", "", False, False, kvpPrefix & "6_DeleteAzureRegistryKeys", g_Trace)
TraceError g_Trace, "Deleting azure registry keys failed."
End If
End Sub
' This function Enables the service if disabled and changes its start mode as requested.
Sub EnableService(serviceName, startMode)
Dim configureServiceCommand, oResults
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("EnableService"))
.setAttribute "ServiceName", serviceName
End With
g_Trace.TraceEvent oTraceEvent
configureServiceCommand = "%SystemRoot%\OEM\WaGuest.exe /configureservicestartmode " & QuoteString(serviceName) & " " & QuoteString(startMode) & " 1"
Set oResults = ExecuteAndTraceWithResults(configureServiceCommand, g_Trace)
If oResults.ExitCode <> 0 Then
Err.Raise vbObjectError + ERROR_ENABLESERVICEFAILED, "GuestAgent.wsf", "Failed to configure service start mode"
Exit Sub
End If
End Sub
Sub StopProcessWait(processName)
Dim stopProcessCommand, oResults
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopProcessWait"))
.setAttribute "ProcessName", processName
End With
g_Trace.TraceEvent oTraceEvent
stopProcessCommand = "%SystemRoot%\OEM\WaGuest.exe /terminateprocess " & QuoteString(processName)
Set oResults = ExecuteAndTraceWithResults(stopProcessCommand, g_Trace)
If oResults.ExitCode <> 0 Then
Err.Raise vbObjectError + ERROR_ENABLESERVICEFAILED, "GuestAgent.wsf", "Failed to kill process"
Exit Sub
End If
End Sub
' This function checks if the service is installed.
Function CheckServiceInstalled(serviceName)
On Error Resume Next
Dim verifyServiceInstalledCommand, serviceInstalledResult, verifyServiceInstalled
verifyServiceInstalled = False
verifyServiceInstalledCommand = "%SystemRoot%\OEM\WaGuest.exe /isserviceinstalled " & QuoteString(serviceName)
Set oResults = ExecuteAndTraceWithResults(verifyServiceInstalledCommand, g_Trace)
If oResults.ExitCode <> 0 Then
Err.Raise vbObjectError + ERROR_SERVICEINSTALLEDNOTVERIFIED, "GuestAgent.wsf", "Failed to verify if the service is installed"
Exit Function
End If
serviceInstalledResult = Trim(Replace(oResults.StdOut, vbCrLf, ""))
If serviceInstalledResult = "true" Then
verifyServiceInstalled = True
Else
verifyServiceInstalled = False
End If
CheckServiceInstalled = verifyServiceInstalled
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)
Dim stopServiceCommand
stopServiceCommand = "%SystemRoot%\OEM\WaGuest.exe /stopservice " & QuoteString(serviceName)
Set oResults = ExecuteAndTraceWithResults(stopServiceCommand, g_Trace)
call StopProcessWait(processName)
TraceError g_Trace, "Stopping process: " + processName + " failed."
End Sub
' This function unregisters a service.
Sub UnregisterService(serviceName, processName)
On Error Resume Next
Dim unregisterServiceCommand
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnregisterService"))
.setAttribute "ServiceName", serviceName
End With
g_Trace.TraceEvent oTraceEvent
unregisterServiceCommand = "%SystemRoot%\OEM\WaGuest.exe /unregisterservice " & QuoteString(serviceName)
Set oResults = ExecuteAndTraceWithResults(unregisterServiceCommand, g_Trace)
If oResults.ExitCode <> 0 Then
Err.Raise vbObjectError + ERROR_SERVICEINSTALLEDNOTVERIFIED, "GuestAgent.wsf", "Failed to unregister the service"
Exit Sub
End If
Set oTraceEvent = g_Trace.CreateEvent("INFO")
oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnregisterService"))
g_Trace.TraceEvent oTraceEvent
End Sub
' This function stops traces for GA logging
Sub StopEventTrace
On Error Resume Next
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopEventTrace"))
.setAttribute "StopGAEvents", "True"
End With
g_Trace.TraceEvent oTraceEvent
ExecuteAndTraceWithResults "%SystemRoot%\System32\logman.exe stop GAEvents", g_trace
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopEventTrace"))
.setAttribute "StopRTEvents", "True"
End With
g_Trace.TraceEvent oTraceEvent
ExecuteAndTraceWithResults "%SystemRoot%\System32\logman.exe stop RTEvents", g_trace
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopEventTrace"))
.setAttribute "StopMetricEvents", "True"
End With
g_Trace.TraceEvent oTraceEvent
ExecuteAndTraceWithResults "%SystemRoot%\System32\logman.exe -ets stop WindowsAzure-GuestAgent-Metrics", g_trace
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("StopEventTrace"))
.setAttribute "StopDiagnosticsEvents", "True"
End With
g_Trace.TraceEvent oTraceEvent
ExecuteAndTraceWithResults "%SystemRoot%\System32\logman.exe -ets stop WindowsAzure-GuestAgent-Diagnostic", g_trace
End Sub
' This function deletes traces for GA logging
Sub DeleteEventTrace
On Error Resume Next
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("DeleteEventTrace"))
.setAttribute "DeleteGAEvents", "True"
End With
g_Trace.TraceEvent oTraceEvent
ExecuteAndTraceWithResults "%SystemRoot%\System32\logman.exe delete GAEvents", g_trace
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("DeleteEventTrace"))
.setAttribute "DeleteRTEvents", "True"
End With
g_Trace.TraceEvent oTraceEvent
ExecuteAndTraceWithResults "%SystemRoot%\System32\logman.exe delete RTEvents", g_trace
End Sub
' This function deletes all the Azure specific folders on the filesystem.
Sub DeleteAzureFolders
On Error Resume Next
Dim gaPath, pluginsPath
Dim fso
Set fso = CreateObject("Scripting.FileSystemObject")
gaPath = fso.BuildPath(WshShell.ExpandEnvironmentStrings("%SYSTEMDRIVE%"), "\WindowsAzure")
pluginsPath = fso.BuildPath(WshShell.ExpandEnvironmentStrings("%SYSTEMDRIVE%"), "\Packages")
call DeleteFolder(gaPath)
call DeleteFolder(pluginsPath)
End Sub
' This function deletes the folder specified in the path parameter.
Sub DeleteFolder(path)
On Error Resume Next
Dim fso : Set fso = CreateObject("Scripting.FileSystemObject")
fso.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", gaPath
.setAttribute "Error", Err.number
.setAttribute "Description", Err.Description
End With
g_Trace.TraceEvent oTraceEvent
Else
Err.number = 0
End If
End Sub
Sub DeleteAzureRegistryKeys
On Error Resume Next
const HKEY_LOCAL_MACHINE = &H80000002
const strComputer = "."
const strAzureKeyPath = "SOFTWARE\Microsoft\Windows Azure"
const strGAKeyPath = "SOFTWARE\Microsoft\GuestAgent"
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
errReturnCode = objReg.DeleteKey(HKEY_LOCAL_MACHINE, strAzureKeyPath)
If errReturnCode = 0 And Err.Number = 0 Then
eventType = "INFO"
Else
eventType = "ERROR"
End If
Set oTraceEvent = g_Trace.CreateEvent(eventType)
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("DeleteAzureRegistryKeys"))
.setAttribute "AzureKeyPath", strAzureKeyPath
.setAttribute "DeleteKey", errReturnCode
End With
g_Trace.TraceEvent oTraceEvent
errReturnCode = objReg.DeleteKey(HKEY_LOCAL_MACHINE, strGAKeyPath)
If errReturnCode = 0 And Err.Number = 0 Then
eventType = "INFO"
Else
eventType = "ERROR"
End If
Set oTraceEvent = g_Trace.CreateEvent(eventType)
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("DeleteAzureRegistryKeys"))
.setAttribute "GAKeyPath", strGAKeyPath
.setAttribute "DeleteKey", errReturnCode
End With
g_Trace.TraceEvent oTraceEvent
End Sub
' This function verifies the OS requirements for installing GuestAgent.
Function VerifyOsRequirements
On Error Resume Next
Dim majorVersion : majorVersion = GetOSCurrentMajorVersionNumber
Dim minorVersion : minorVersion = GetOSCurrentMinorVersionNumber
If TraceError(g_Trace, "VerifyOsRequirements: Failed to read the major and minor versions - will inject GuestAgent anyway") <> 0 Then
VerifyOsRequirements = True
Exit Function
End If
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("VerifyOsRequirements"))
.setAttribute "OsMajorVersion", majorVersion
.setAttribute "OsMinorVersion", minorVersion
End With
g_Trace.TraceEvent oTraceEvent
VerifyOsRequirements = ((majorVersion > 6) Or (majorVersion = 6 And minorVersion > 0))
End Function
' This function returns the w.x.y.z version components of the parameterized version string as a four-element array
' raising an error if the parameterized version string cannot be parsed into its version components.
' If the parameterized version string has fewer than four components, 0 will be returned for the missing components' values
Private Function GetVersionComponents(versionStr)
Const ERROR_EMPTY_VERSION_STRING = 13
Dim components
Dim w, x, y, z
w = 0
x = 0
y = 0
z = 0
components = Split(versionStr, ".") ' Split raises an error if versionString is Null, returns empty array if versionStr is ""
If UBound(components) < 0 Then
Err.Raise vbObjectError + ERROR_EMPTY_VERSION_STRING, "GuestAgent.wsf", "GetVersionComponents: The parameterized version string is empty"
End If
If UBound(components) >= 0 Then
w = CLng(components(0))
End If
If UBound(components) >= 1 Then
x = CLng(components(1))
End If
If UBound(components) >= 2 Then
y = CLng(components(2))
End If
If UBound(components) >= 3 Then
z = CLng(components(3))
End If
GetVersionComponents = Array(w, x, y, z)
End Function
' Unzips the GuestAgent package and returns the path to the directory in which it was extracted to
Sub UnzipGuestAgentPackage
On Error Resume Next
Dim objGAZipLocation
Dim extractToPath, zipPath, scriptDir
Dim fso
Dim appendDirName
Const FOF_SILENT = &H4&
Const FOF_NOCONFIRMATION = &H10&
Const FOF_NOERRORUI = &H400&
Set fso = CreateObject("Scripting.FileSystemObject")
scriptDir = fso.GetParentFolderName(Me.WScript.ScriptFullName)
zipPath = fso.BuildPath(scriptDir, "GuestAgent\")
zipPath = fso.BuildPath(zipPath, oGAPackageName)
appendDirName = ""
extractToPath = fso.BuildPath(WshShell.ExpandEnvironmentStrings("%SYSTEMDRIVE%"), "\WindowsAzure\")
'If the WindowsAzure folder does not exist create it.
If Not fso.FolderExists(extractToPath) Then
fso.CreateFolder(extractToPath)
If Err.number <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnzipGuestAgentPackage"))
.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("UnzipGuestAgentPackage"))
.setAttribute "WindowsAzureFolderExists", CStr(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 = fso.BuildPath(extractToPath, "Packages" & appendDirName & "\")
oExtractedAgentLocation = extractToPath
'If the Packages folder does not exist create it.
If Not fso.FolderExists(extractToPath) Then
fso.CreateFolder(extractToPath)
If Err.number <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnzipGuestAgentPackage"))
.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("UnzipGuestAgentPackage"))
.setAttribute "WindowsAzurePackagesFolderExists", CStr(True)
End With
g_Trace.TraceEvent oTraceEvent
End If
Dim extractorExePath, extractorExeCmdString
extractorExePath = fso.BuildPath(scriptDir, "VmAgentPackageExtractor\")
extractorExeCmdString = extractorExePath & "PackageExtractor.exe """ & zipPath & " "" """ & extractToPath & " """
ExecuteAndTraceWithResults extractorExeCmdString, g_Trace
If TraceError(g_Trace, "UnzipGuestAgentPackage: Failed to unzip VMAgent package") = 0 Then
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("UnzipGuestAgentPackage"))
.setAttribute "ZipLocation", zipPath
.setAttribute "ExtractionLocation", extractToPath
End With
g_Trace.TraceEvent oTraceEvent
End If
End Sub
' This procedure registers the transparent installer service (RdAgent / WaAppAgent.exe)
Sub ConfigureRdAgentService(offlineMode)
On Error Resume Next
Dim objWMIService, objService, servicePath, startMode
Dim errReturnCode ' only used (logged) when RdAgent service doesn't exist and must be created
Dim fso
Const OWN_PROCESS = 16
Const NOT_INTERACTIVE = False
Const NORMAL_ERROR_CONTROL = 1
Set objWMIService = GetObject("winmgmts:\\.\root\cimv2")
Set objService = objWMIService.Get("Win32_BaseService")
Set fso = CreateObject("Scripting.FileSystemObject")
servicePath = fso.BuildPath(oExtractedAgentLocation, "\WaAppAgent.exe")
If CBool(offlineMode) = True Then
' In offline mode, we don't want the service starting on next boot
' We set its start mode to disabled with the expectation that a
' subsequent provisioning pass will enable the service
startMode = "Disabled"
Else
startMode = "Automatic"
End If
If oServiceAlreadyInstalled = False Then
' if the service is not installed, then the correct version to use is the HOST's version
oGuestAgentBinaryLocation = oExtractedAgentLocation
' Create service
errReturnCode = objService.Create("RdAgent", "RdAgent", servicePath, OWN_PROCESS, NORMAL_ERROR_CONTROL, startMode, _
NOT_INTERACTIVE, NULL, NULL )
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ConfigureRdAgentService"))
.setAttribute "CreateService", errReturnCode
.setAttribute "StartMode", startmode
End With
g_Trace.TraceEvent oTraceEvent
Else
' if the version to install is not newer than the existing version, leave the existing version installed but re-configure it just-in-case something has been changed
Dim existingServicePath, existingServiceVersionStr, serviceVersionStr, existingServiceVersionComponents, serviceVersionComponents
existingServicePath = fso.BuildPath(oOldGuestAgentBinLocation, "\WaAppAgent.exe")
existingServiceVersionStr = fso.GetFileVersion(existingServicePath)
serviceVersionStr = fso.GetFileVersion(servicePath)
existingServiceVersionComponents = GetVersionComponents(existingServiceVersionStr)
serviceVersionComponents = GetVersionComponents(serviceVersionStr)
' the y component is the branch ID and can be safely ignored
' serviceVersionComponents(2) <= existingServiceVersionComponents(2) And _
If (serviceVersionComponents(0) <= existingServiceVersionComponents(0) And _
serviceVersionComponents(1) <= existingServiceVersionComponents(1) And _
serviceVersionComponents(3) <= existingServiceVersionComponents(3)) Then ' z increases with every new version where x (minor) remains the same
oGuestAgentBinaryLocation = fso.GetParentFolderName(existingServicePath)
oOldGuestAgentBinLocation = fso.GetFolder(oExtractedAgentLocation).Path ' set to extracted location for clean-up, post-configuration
Else
oGuestAgentBinaryLocation = fso.GetParentFolderName(servicePath)
End If
' Change service settings with resolved path
servicePath = fso.BuildPath(oGuestAgentBinaryLocation, "\WaAppAgent.exe")
call SetServicePathInRegistry("RdAgent", servicePath)
If TraceError(g_Trace, "Setting the RdAgent service path in registry failed.") <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ConfigureRdAgentService"))
.setAttribute "Failed to update RdAgent path", Err.number
End With
g_Trace.TraceEvent oTraceEvent
Exit Sub
End If
servicePath = fso.BuildPath(oGuestAgentBinaryLocation, "\Telemetry\WindowsAzureTelemetryService.exe")
call SetServicePathInRegistry("WindowsAzureTelemetryService", servicePath)
If TraceError(g_Trace, "Setting the WindowsAzureTelemetryService service path in registry failed.") <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ConfigureRdAgentService"))
.setAttribute "Failed to update WindowsAzureTelemetryService path", Err.number
End With
g_Trace.TraceEvent oTraceEvent
Exit Sub
End If
servicePath = fso.BuildPath(oGuestAgentBinaryLocation, "\GuestAgent\WindowsAzureGuestAgent.exe")
' There are two versions of GuestAgent. The newer version removes the GuestAgent folder and thus we need to double check here
' TODO: We should evaluate the possibility to remove the setting as now the newer version RdAgent does set the path and they
' have the best knowledge where the GuestAgent should be.
If Not fso.FileExists(servicePath) Then
servicePath = fso.BuildPath(oGuestAgentBinaryLocation, "\WindowsAzureGuestAgent.exe")
End If
call SetServicePathInRegistry("WindowsAzureGuestAgent", servicePath)
If TraceError(g_Trace, "Setting the WindowsAzureGuestAgent service path in registry failed.") <> 0 Then
Set oTraceEvent = g_Trace.CreateEvent("ERROR")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ConfigureRdAgentService"))
.setAttribute "Failed to update WindowsAzureGuestAgent path", Err.number
End With
g_Trace.TraceEvent oTraceEvent
Exit Sub
End If
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("ConfigureRdAgentService"))
.setAttribute "GuestAgentBinariesLocation", oGuestAgentBinaryLocation
End With
g_Trace.TraceEvent oTraceEvent
End If
End Sub
' Start the installer service
Sub StartRdAgentService
On Error Resume Next
Dim startServiceCommand
startServiceCommand = "%SystemRoot%\OEM\WaGuest.exe /startservice RdAgent"
Set oResults = ExecuteAndTraceWithResults(startServiceCommand, g_Trace)
If oResults.ExitCode <> 0 Then
Err.Raise vbObjectError + ERROR_STARTSERVICE, "GuestAgent.wsf", "Failed to start service"
Exit Sub
End If
End Sub
' Set VMType information in registry for GA to use at runtime
Sub SetVmTypeInRegistry
On Error Resume Next
const HKEY_LOCAL_MACHINE = &H80000002
const strComputer = "."
const strKeyPath = "SOFTWARE\Microsoft\Windows Azure"
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
objReg.CreateKey HKEY_LOCAL_MACHINE, strKeyPath
strValueName = "VMType"
strTypeValue = "IAAS"
objReg.SetStringValue HKEY_LOCAL_MACHINE, strKeyPath, strValueName, strTypeValue
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("SetVmTypeInRegistry"))
.setAttribute strValueName, strTypeValue
End With
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("SetRdAgentServicePathInRegistry"))
.setAttribute "ServiceName", serviceName
.setAttribute "ServiceImagePath", servicePath
End With
g_Trace.TraceEvent oTraceEvent
End Sub
' Set the incarnation in registry for GA to use at runtime
Sub SetGAParamsInRegistry(offlineMode)
On Error Resume Next
Dim servicePath, strFileVer, strProvisioningTime
Set objFSO = CreateObject("Scripting.FileSystemObject")
servicePath = objFSO.BuildPath(oGuestAgentBinaryLocation, "\TransparentInstaller.dll")
strFileVer = objFSO.GetFileVersion(servicePath)
strProvisioningTime = FormatDateTime(Now)
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("SetGAParamsInRegistry"))
.setAttribute "BasePath", oGuestAgentBinaryLocation
.setAttribute "ServicePath", servicePath
.setAttribute "FileVersion", strFileVer
End With
g_Trace.TraceEvent oTraceEvent
const HKEY_LOCAL_MACHINE = &H80000002
const strComputer = "."
const strKeyPath = "SOFTWARE\Microsoft\GuestAgent"
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
objReg.CreateKey HKEY_LOCAL_MACHINE, strKeyPath
objReg.SetStringValue HKEY_LOCAL_MACHINE, strKeyPath, "Incarnation", strFileVer
If offlineMode = False Then
objReg.SetStringValue HKEY_LOCAL_MACHINE, strKeyPath, "VmProvisionedAt", strProvisioningTime
End If
objReg.SetStringValue HKEY_LOCAL_MACHINE, strKeyPath, "ManifestTimeStamp", ""
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("SetGAParamsInRegistry"))
.setAttribute "Incarnation", strFileVer
If offlineMode = False Then
.setAttribute "VmProvisionedAt", strProvisioningTime
End If
.setAttribute "ManifestTimeStamp", ""
End With
g_Trace.TraceEvent oTraceEvent
End Sub
' Set the provisioning time in registry for GA to use at runtime
Sub SetGAParamsInRegistryOfflined
On Error Resume Next
Dim strProvisioningTime : strProvisioningTime = FormatDateTime(Now)
const HKEY_LOCAL_MACHINE = &H80000002
const strComputer = "."
const strKeyPath = "SOFTWARE\Microsoft\GuestAgent"
Set objReg = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\default:StdRegProv")
objReg.CreateKey HKEY_LOCAL_MACHINE, strKeyPath
objReg.SetStringValue HKEY_LOCAL_MACHINE, strKeyPath, "VmProvisionedAt", strProvisioningTime
Set oTraceEvent = g_Trace.CreateEvent("INFO")
With oTraceEvent.appendChild(oTraceEvent.ownerDocument.createElement("SetGAParamsInRegistryOfflined"))
.setAttribute "VmProvisionedAt", strProvisioningTime
End With
g_Trace.TraceEvent oTraceEvent
End Sub
' Get service install location the incarnation in registry for GA 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
Set fso = CreateObject("Scripting.FileSystemObject")
GetServiceInstallLocation = fso.GetParentFolderName(servicePath)
End Function
</script>
</component>
</package>