
OK, sou um programador C # que está tentando agilizar a implantação de um aplicativo de formulário do Windows personalizado que herdei e criei um instalador com WiX (esse aplicativo precisará ser reinstalado regularmente enquanto estou fazendo alterações nele). Eu realmente não estou acostumado a administrar coisas do tipo (ou vbs, ou WMI, ou servidores de terminal, ou Citrix, e até mesmo WiX e MSI não são coisas com as quais costumo lidar), mas até agora juntei alguns vbs e tenho um objetivo final em mente. O msi funciona e eu o instalei a partir da unidade O: mapeada em minha máquina de desenvolvimento e durante o RDP em uma máquina Citrix.
Objetivo final:Implante o código escrito em minha máquina de desenvolvimento e compilado em um MSI (que eu possa melhorar dentro dos limites do WiX e tudo o que o mecanismo do Windows Installer permitir) no cluster de máquinas Citrix aos quais meus usuários têm acesso.
O que estou faltando no meu script para executar o MSI nas máquinas remotas?
Disposição:
- A máquina A é minha máquina de desenvolvimento e possui o script vbs e o arquivo msi (XP SP3)
- As máquinas C1 - C6 são os servidores Citrix que precisam que o aplicativo seja instalado via msi (Server 2003 R2 SP2)
- Opcionalmente, também existe um recurso de rede compartilhado que todas as máquinas podem acessar.
Roteiro:
'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
Também tentei usar isso para instalar, ele não retorna um código de erro, mas também não instala o msi, e isso me faz pensar se o comando change user /install está realmente funcionando.
errReturn = objProcess.Create _
("cmd.exe /c msiexec /i ""O:\Citrix Deployment\Setup.msi"" /quiet")
Wscript.Echo errReturn
@tony O arquivo é copiado perfeitamente, mas então recebo isto:
ERROR:
Code = 0x80070005
Description = Access is denied.
Facility = Win32
Preciso usar outra conta de usuário (mesmo domínio) para as máquinas Citrix, e é por isso que usei:
Set objLocator = CreateObject("WbemScripting.SWbemLocator")
Set objWMIService = objLocator.ConnectServer( .....
Finalmente usei um script do PowerShell para isso com base nas sugestões e sugestões de Tony, e ele parece e funciona muito mais limpo.
Embora obter o método de instalação da classe Win32_Product ainda pareça um pouco complicado (em comparação com o comando WMIC), é o que o Technet sugere:
Link 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")
}
Responder1
por um lado, o Citrix tem sua própria tecnologia de implantação; em segundo lugar, você está dizendo que seu método de implantação falha de alguma forma? Nesse caso, espero que seja um problema de representação. Mas não posso dizer pela sua explicação.
a seguir está um atalho para todo o código que você tem
na primeira
cópia do arquivo.msi \citrixservername\c$\pathtoyourfile
wmic /node:citrixservername chamada de produto install true,"" , "c:\PathToYour\File.msi"
observe que o arquivo de instalação é copiado localmente para o servidor primeiro; se você não fizer isso, terá um problema de representação!