Instalación remota de un msi en servidores citrix usando WMI

Instalación remota de un msi en servidores citrix usando WMI

Bien, soy un programador de C# que está tratando de optimizar la implementación de una aplicación personalizada de Windows Form que heredé y para la que creé un instalador con WiX (esta aplicación deberá reinstalarse periódicamente a medida que le hago cambios). Realmente no estoy acostumbrado a cosas de tipo administrador (ni vbs, ni WMI, ni servidores de terminal, ni Citrix, e incluso WiX y MSI no son cosas con las que suelo tratar), pero hasta ahora he reunido algunos vbs y tengo un objetivo final. en mente. El msi funciona y lo instalé desde la unidad O: asignada en mi máquina de desarrollo y mientras tenía RDP en una máquina Citix.

Objetivo final:Implementar código escrito en mi máquina de desarrollo y compilado en un MSI (que puedo mejorar dentro de los límites de WiX y lo que permita Windows Installer Engine) en el grupo de máquinas Citrix al que tienen acceso mis usuarios.

¿Qué me falta en mi script para que MSI se ejecute en las máquinas remotas?

Disposición:

  • La máquina A es mi máquina de desarrollo y tiene el script vbs y el archivo msi (XP SP3)
  • Las máquinas C1 - C6 son los servidores Citrix que necesitan que la aplicación les instale a través del msi (Server 2003 R2 SP2)
  • Opcionalmente, también hay un recurso de red compartido al que todas las máquinas pueden acceder.

Guion:

'Set WMI Constants
Const wbemImpersonationLevelImpersonate = 3
Const wbemAuthenticationLevelPktPrivacy = 6

'Set whether this is installing to the debug Citrix Servers
Const isDebug = true

'Set MSI location
'Network location yields error 1619 (This installation package could not be opened.)
msiLocation = "\\255.255.255.255\odrive\Citrix Deployment\Setup.msi"
'Directory on machine A yields error 3 (file not found)
'msiLocation = "C:\Temp\Deploy\Setup.msi"
'Mapped network drive (on both machines) yield error 3 (file not found)
'msiLocation = "O:\Citrix Deployment\Setup.msi"

'Set login information
strDomain = "MyDomain" 
Wscript.StdOut.Write "user name:"
strUser = Wscript.StdIn.ReadLine 
Set objPassword = CreateObject("ScriptPW.Password")
Wscript.StdOut.Write "password:"
strPassword = objPassword.GetPassword()

'Names of Citrix Servers
Dim citrixServerArray
If isDebug Then
    citrixServerArray = array("C4")
Else
    'citrixServerArray = array("C1","C2","C3","C5","C6")
End If

'Loop through each Citrix Server
For Each citrixServer in citrixServerArray

    'Login to remote computer
    Set objLocator = CreateObject("WbemScripting.SWbemLocator")
    Set objWMIService = objLocator.ConnectServer(citrixServer, _
        "root\cimv2", _
         strUser, _
         strPassword, _
         "MS_409", _
         "ntlmdomain:" + strDomain)

    'Set Remote Impersonation level
    objWMIService.Security_.ImpersonationLevel = wbemImpersonationLevelImpersonate
    objWMIService.Security_.AuthenticationLevel = wbemAuthenticationLevelPktPrivacy
     
    'Reference to a process on the machine
    Dim objProcess : Set objProcess = objWMIService.Get("Win32_Process")

    'Change user to install for terminal services
    errReturn = objProcess.Create _
        ("cmd.exe /c change user /install", Null, Null, intProcessID)   
    WScript.Echo errReturn
    
    'Install MSI here
    'Reference to a product on the machine
    Set objSoftware = objWMIService.Get("Win32_Product")
    'All users set in option parameter, I'm led to believe that the third parameter is actually ignored
    'http://www.webmasterkb.com/Uwe/Forum.aspx/vbscript/2433/Installing-programs-with-VbScript
    errReturn = objSoftware.Install(msiLocation,"ALLUSERS=2 REBOOT=ReallySuppress",True)
    Wscript.Echo errReturn
            
    'Change user back to execute
    errReturn = objProcess.Create _
        ("cmd.exe /c change user /execute", Null, Null, intProcessID)
    WScript.Echo errReturn

Next

También intenté usar esto para instalar, no devuelve un código de error, pero tampoco instala el msi, y me hace preguntarme si el comando cambiar usuario /instalar realmente funciona.

errReturn = objProcess.Create _
    ("cmd.exe /c msiexec /i ""O:\Citrix Deployment\Setup.msi"" /quiet")
Wscript.Echo errReturn

@tony El archivo se copia bien, pero luego aparece esto:

ERROR:
Code = 0x80070005
Description = Access is denied.
Facility = Win32

Necesito usar otra cuenta de usuario (aunque el mismo dominio) para las máquinas Citrix, por eso usé:

Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMIService = objLocator.ConnectServer( .....

Finalmente utilicé un script de PowerShell para esto basado en los aportes y sugerencias de Tony, y se ve y actúa mucho más limpio.

Aunque obtener el método de instalación de la clase Win32_Product todavía parece un poco complicado (en comparación con el comando WMIC), es lo que sugiere Technet:

Enlace http://technet.microsoft.com/en-us/library/dd347651.aspx

#$servers = 'C1' , 'C2', 'C3' , 'C5', 'C6'
$servers = , 'C4'
$MyCredential = Get-Credential MyDomain\otherusername

foreach($server in $servers)
{
    Copy-Item -LiteralPath C:\Temp\Deploy\Setup.msi -Destination \\$server\c$\Temp\Setup.msi -Force
    (Get-WmiObject -ComputerName $server -Credential $MyCredential -List | `
    Where-Object -FilterScript {$_.Name -eq "Win32_Product"}).Install("C:\TEMP\Setup.msi")
}

Respuesta1

Por un lado, Citix tiene su propia tecnología de implementación. En segundo lugar, ¿está diciendo que su método de implementación falla de alguna manera? Si es así, espero que sea un problema de suplantación. Pero realmente no puedo decirlo por tu explicación.

el siguiente es un acceso directo a todo el código que tiene en
la primera
copia del archivo.msi \citrixservername\c$\pathtoyourfile

wmic /nodo:citrixservername llamada del producto instalar verdadero",", "c:\PathToYour\File.msi"

Tenga en cuenta que el archivo de instalación se copia localmente en el servidor primero; si no hace esto, tendrá un problema de suplantación.

información relacionada