# installMSiRemoteComputers.ps1
# version 0.0.1
$computernames='REMOTEPC001','REMOTEPC002'
$thisMsiFile='C:\Temp\something.msi'
$appName='testapp'
$desiredVersion='1.0'
$maxWaitSeconds=120
function installMsiOnRemoteComputers($computernames,$msiFile,$appName,$desiredVersion,$maxWaitSeconds){
function installMsiOnRemoteComputer{
param(
$computernames=$env:computername,
$msiFile,
$destinationLocalTempFolder='C:\Temp',
$testFileName='testfile.txt'
)
function translateLocalPathToSmbPath($computername,$localPath,$testFileName){
$adminDriveLetter=[regex]::match($localPath,'^([\w\W])\:').captures.groups[1].value
$partialPath=[regex]::match($localPath,'^([\w\W])\:(.*)').captures.groups[2].value
$testPath=join-path "\\$computername\$adminDriveLetter`$" "$partialPath"
if(!(test-path $testPath)){
try{
New-Item -Path $testPath -ItemType "directory" -force
}catch{
write-warning "Unable to create $testPath"
return $false
}
}
try{
$null=New-Item -Path $testPath -Name $testFileName -ItemType "file" -force
Remove-Item "$testPath\$testFileName" -force
return $testPath
}catch{
write-warning "Unable to read or write to $testPath"
return $false
}
}
$results=[hashtable]@{}
$msiLocalFilePath=join-path $destinationLocalTempFolder $(split-path $msiFile -leaf)
foreach ($computername in $computernames){
$translatedDestination=translateLocalPathToSmbPath $computername $destinationLocalTempFolder $testFileName
if($translatedDestination){
copy-item $msiFile $translatedDestination
}else{
write-warning "Unable to copy $msiFile to $translatedDestination"
$results+=[hashtable]@{$computername=$false}
continue
}
$psSession=new-psSession $computername
if($psSession.State -eq 'Opened'){
$result=invoke-command -session $pssession -scriptblock{
param($filePath)
$file=gi $filePath
$DataStamp = get-date -Format yyyyMMddTHHmmss
$logFile ="C:\" + '{0}-{1}.log' -f $file.name,$DataStamp
$MSIArguments = @(
"/i"
('"{0}"' -f $file.fullname)
"/qn"
"/norestart"
"/L*v"
$logFile
)
try{
[diagnostics.process]::start("msiexec.exe", $MSIArguments).WaitForExit()
write-host "MSIEXEC has been called for file $filePath on $env:computername"
return $true
}catch{
write-warning $_
return $false
}
} -Args $msiLocalFilePath
# Note Error:
# Resolved by not using -wait switch and calling [diagnostics.process] instead of Start-Process "msiexec.exe"
# Although, this error would still being thrown with the [diagnostics.process] result of success
# Processing data for a remote command failed with the following error message: The I/O operation has been aborted
# because of either a thread exit or an application request. For more information, see the about_Remote_Troubleshooting
# Help topic.
# + CategoryInfo : OperationStopped: (:String) [], PSRemotingTransportException
# + FullyQualifiedErrorId : JobFailure
# + PSComputerName :
$results+=[hashtable]@{$computername=$result}
remove-psSession $psSession
}else{
write-warning "Unable to connect to $computername"
$results+=[hashtable]@{$computername="Unable to connect to $computername"}
}
}
return $results
}
$results=[hashtable]@{}
foreach($computername in $computernames){
try{
installMsiOnRemoteComputer $computername $msiFile
write-host "Now waiting up to $maxWaitSeconds seconds before checking on the install result"
$timer=[System.Diagnostics.Stopwatch]::StartNew()
do{
start-sleep -seconds 5
$appVersionPassed=invoke-command -computername $computername {
param($appName,$desiredVersion)
$matchedApp=Get-WmiObject -Class Win32_Product -Filter "Name='$appName'"
if($matchedApp.Version -eq $desiredVersion){
return $true
}else{
return $false
}
} -Args $appName,$desiredVersion
if($appVersionPassed){
write-host "$appName $desiredVersion installed on $computername successfully"
$results+=[hashtable]@{$computername='$appName $desiredVersion installed'}
}
$exitCondition=$timer.elapsed.totalseconds -ge $maxWaitSeconds
}until($appVersionPassed -or $exitCondition)
if(!$appVersionPassed){
write-host "$appName $desiredVersion has NOT been installed successfully on $computername"
$results+=[hashtable]@{$computername="$appName $desiredVersion NOT installed"}
}
$timer.stop()
}catch{
write-warning $_
$results+=[hashtable]@{$computername="$_"}
exit 1
}
}
return $results
}
installMsiOnRemoteComputers $computernames $thisMsiFile $appName $desiredVersion $maxWaitSeconds
October 25, 2022October 25, 2022
0 Comments