Remote installation

I’m trying to install a piece of software by running a batch file which calls msiexec with a transform. My script goes like this
foreach($computer in $computers){
if(Test-Connection $computer -quiet){
if((Test-Path “\$computer\c$\software”) -eq $false){
Copy-Item $source -Destination “\$computer\c$\software” -Recurse -Force
$session=New-PSSession -Computer $computer -Credential $cred
$job = Invoke-Command -SessionName $session -Computername $computer -ScriptBlock {Start-Process “c:\Software\run.bat”} -AsJob
$job | Wait-Job
Remove-PSSession $session
}
else …

My folder gets copied and Job state says Completed when the script finishes yet the software isn’t getting installed. Some help would be appreciated.

First, in:

"\\$computer\c$\software"

You should probably escape the second dollar sign by preceding it with a backtick. Just for better long-term reading and maintenance.

I assume Run.bat works fine when you run it interactively yourself? It’s possible that the installer is expecting to find a logged-on user and profile. That’s often the case when they try to create Start menu icons and other per-user data. Running the batch file remotely doesn’t provide a logged-in user profile, and some installers will fail in that situation. There isn’t anything you can do about that other than modifying the installer so that it can work when there’s no active user profile loaded.

The batch file actually calls the msiexec installer which in turn uses a transform an dyes it works interactively. I tried replacing New-PSSession simply leaving

Invoke-Command -computername $computer -Authentication Kerberos -ScriptBlock {& msiexec.exe “/i ‘\$computer\c`$\software\install.msi’ /T `”\$computer\c`$\software\some transform file.mst`" /qb" -Wait -Passthru}
but still no success so as you suggested possibly this installation needs a logged in user indeed which makes it quite a pain to install on over 50 Server 2008 R2 hosts.

Yeah, unfortunately there are more badly-made MSIs than goodly-made ones.

Actually, I’ll point out another possibility, now that I can see what your code is attempting more clearly.

Invoke-Command -computername $computer -Authentication Kerberos -ScriptBlock {& msiexec.exe "/i '\\$computer\c`$\software\install.msi' /T `"\\$computer\c`$\software\some transform file.mst`" /qb" -Wait -Passthru}

Point 1:
You’re sending a command to $computer via Remoting, and asking $computer to connect to \$computer\c$\etc. That’s a “double hop,” meaning the attempt to access the UNC will be un-authenticated and, because it’s an admin share (C$), will likely not work. It doesn’t matter than the computer is accessing itself, it’s still incurring a second “network access” hop. Try providing a local path (e.g., C:) instead.

Point 2:
Within the -ScriptBlock you’re passing to Invoke-Command, $computer actually has no context. The ScriptBlock is executed on the remote machine, where $computer was never defined. So your UNC is “\\c$\software\install.msi” which is likely not going to work. On PowerShell v3 and later, you can use $using:computer to pass the contents of your local $computer into the remote script block for execution, but this will just get you back to Point 1.

My bad, I was typing from memory hence the confusion but the script actually uses local path in ScriptBlock. Looks like I learned something new thrugh that mistake. Never heard of $using:xxx. Thanks for that :slight_smile:

In that case, it’s probably the MSI not playing well ;).